<!DOCTYPE html>
<html lang="en">
<head>
  <title>Service Workers</title>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <style>
body {
  padding: 2em 1em 2em 70px;
  margin: 0;
  font-family: 'Open Sans', sans-serif;
  color: black;
  background: white;
  background-position: top left;
  background-attachment: fixed;
  background-repeat: no-repeat;

  line-height: 1.5em;
  font-size: 14px;
}

:link { color: #00C; background: transparent }
:visited { color: #609; background: transparent }
a:active { color: #C00; background: transparent }

a:link img,
a:visited img {
  border: none;
}

.logo > a {
  border-bottom: none;
}

h1, h2, h3, h4 {
  font-family: 'Open Sans', sans-serif;
  color: #005A9C;
  padding: 0;
  margin: 1.5em 0 0.3em 0;
}

h1 {
  font-size: 3em;
  line-height: 1em;
  margin: 1em 0;
}

h1.title {
  font-size: 2em;
  font-family: sans-serif;
}

h2, h3 {
  margin: 1.5em 0 0.3em 0;
}

article, aside, footer, header, hgroup, main, nav, section {
  display: block;
}

header {
  font-weight: bold;
  margin-top: 20px;
  margin-bottom: 20px;
}

header::after {
clear: both;
display: block;
content: " ";
height: 0;
}

section h1 {
  display: inline;
  font-size: 100%;
  font-weight: bold;
}

code {
  background-color: #eee;
  font-family: 'Droid Sans Mono', monospace;
}

body > pre.prettyprint,
body > section pre {
  background-color: #eee;
  padding: 0 2em 1em 2em;
  margin: 0;
  border: none;
}

header > ul {
  font-family: 'Open Sans', sans-serif;
  font-size: 0.8em;
  list-style: none;
  margin: 0 -1em;
  padding: 0.3em 0;
  background-color: #eee;
}

header > ul > li {
  display: inline;
  margin: 0 0 0 1em;
}

header > ul > li:nth-of-type(3) {
  display: inline;
  margin: 0 0 0 5em;
}

header > ul a {
  color: #666;
}

header > ul a:hover {
  color: #000;
}

var {
  color: #005A9C;
  font-style: normal;
}

.section-number, .anchor > a {
color: #005A9C;
}

.anchor {
padding-right: 1em;
font-size: 0.8em;
float: right;
text-decoration: none;
}

.fixme {
  display: block;
  padding: 10px 0 0 20px;
  border-left: 5px solid #E05252;
}


.fixme:before {
  content: 'To be addressed';
  float: right;
  display: block;
  padding: 2px 10px;
  background-image: -webkit-linear-gradient(top left, #FFFFFF 0%, #FBE9E9 100%);
  background-image: linear-gradient(to bottom right, #FFFFFF 0%, #FBE9E9 100%);
  font-size: 0.9em;
}

.note {
  color: green;
  font-weight: bold;
  font-style: italic;
  padding-left: 2em;
}

.note:before {
  content: "Note: ";
}

.warning:before {
  content: "WARNING: ";
  font-weight: bold;
}

.warning {
  padding: 10px 10px;
  width: 100%;
  background: #fffaba;
  box-sizing: border-box;
}

dfn {
  font-style: normal;
  font-weight: bold;
  background-color: #f9f9f9;
  padding: 0 2px;
  outline: 1px solid #eee;
}

dfn > code {
  background-color: transparent;
}

dfn.no-references {
  background-color: #ffefef;
}

dfn:target, a:target {
  background-color: #FFFF91;
}

a {
  color: black;
  text-decoration: none;
  border-bottom: 1px solid #666;
}

a[href*=dfn-] {
  border-bottom: 1px dotted #ccc;
}

div.informative:before {
  content: 'Informative';
  float: right;
  display: block;
  padding: 2px 10px;
  background-image: -webkit-linear-gradient(top left, #FFFFFF 0%, #D3EEDF 100%);
  background-image: linear-gradient(to bottom right, #FFFFFF 0%, #D3EEDF 100%);
  font-size: 0.9em;
}

div.informative {
  padding: 10px 0 0 20px;
  border-left: 5px solid #D3EEDF;
}

div.monkeypatch:before {
  content: 'Monkeypatch';
  float: right;
  display: block;
  padding: 2px 10px;
  background-image: -webkit-linear-gradient(top left, #FFFFFF 0%, #D3EEDF 100%);
  background-image: linear-gradient(to bottom right, #FFFFFF 0%, #D3EEDF 100%);
  font-size: 0.9em;
}

div.monkeypatch {
  padding: 10px 0 0 20px;
  border-left: 5px solid #EEE5D3;
}

div.deprecated:before {
  content: 'Deprecated parts';
  float: right;
  display: block;
  padding: 2px 10px;
  background-image: -webkit-linear-gradient(top left, #FFFFFF 0%, #fffaba 100%);
  background-image: linear-gradient(to bottom right, #FFFFFF 0%, #fffaba 100%);
  font-size: 0.9em;
}

div.deprecated {
  opacity: 0.6;
}

table {
  border: 1px solid #ccc;
}
table code {
  background-color: transparent;
}
td, th {
  padding: 0.5em;
  vertical-align: top;
}
td {
  border-bottom: 1px solid #ddd;
}
tr:last-of-type td {
  border-bottom: none;
}
th {
  text-align: left;
  background-color: #eee;
}
dt, dd {
  margin-top: 0;
  margin-bottom: 0;
}
dt {
  font-weight: bold;
}
dd {
  padding-bottom: 7px;
}

div.algorithm {
  padding: 0 0 0 20px;
  border-left: 5px solid #EAF7F9;
}
pre {
  background-color: #eee;
  padding: 0.5em 1em 0.5em 1em;
  margin: 0;
  border: none;
}
code {
  background-color: #eee;
  font-family: 'Droid Sans Mono', monospace;
  font-size: 0.9em;
}
code > ins {
  background-color: #BBFFDF;
  text-decoration: none;
}
code > del {
  background-color: #FF979D;
}
nav > ol {
  font-size: 0.9em;
}
nav ol {
  font-weight: normal;
  padding-left:0;
  margin-left: 0;
  font-family: 'Open Sans', sans-serif;
}

/* Browsers don't support ::marker or display:marker, so emulate it. */
nav li {
  list-style-type: none;
}
nav.marker { display: inline-block; }
nav li .marker { width: 1em; text-align: left; }
nav ol ol { margin-left: 1.75em; }
nav li li .marker { width: 2em; }
nav ol ol ol { margin-left: 2em; }
nav li li li .marker { width: 3em; }
nav ol ol ol ol { margin-left: 3em; }
nav li li li li .marker { width: 3.25em; }
  </style>
  <link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/W3C-WD" type="text/css">
  <meta name="bug.short_desc" content="[ServiceWorker]: ">
  <meta name="bug.product" content="WebAppsWG">
  <meta name="bug.component" content="ServiceWorker">
</head>
<body>

<div class="head">
  <div class="logo">
    <a href="//www.w3.org/"><img width="72" height="48" src="//www.w3.org/Icons/w3c_home" alt="W3C"></a>
  </div>

  <h1 class="title">Service Workers</h1>
  <h2 id="w3c-working-draft-18-november-2014">W3C Working Draft 18 November 2014</h2>
  <dl>
  <dt>This version</dt>
    <dd><a href="http://www.w3.org/TR/2014/WD-service-workers-20141118/">http://www.w3.org/TR/2014/WD-service-workers-20141118/</a></dd>
  <dt>Latest published version</dt>
    <dd><a href="http://www.w3.org/TR/service-workers/">http://www.w3.org/TR/service-workers/</a></dd>
  <dt>Latest editor's draft</dt>
    <dd><a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/">https://slightlyoff.github.io/ServiceWorker/spec/service_worker/</a></dd>
  <dt>Previous version</dt>
    <dd><a href="http://www.w3.org/TR/2014/WD-service-workers-20140508/">http://www.w3.org/TR/2014/WD-service-workers-20140508/</a></dd>
  <dt>Revision history</dt>
    <dd><a id="log" href="https://github.com/slightlyoff/ServiceWorker/commits/master">https://github.com/slightlyoff/ServiceWorker/commits/master</a></dd>
  <dt>Participate</dt>
    <dd>Discuss on <a href="http://lists.w3.org/Archives/Public/public-webapps/">public-webapps@w3.org</a> (<a href="http://www.w3.org/2008/webapps/">Web Applications Working Group</a>)</dd>
    <dd><a href="https://github.com/slightlyoff/ServiceWorker/issues">File bugs</a></dd>
  <dt>Editors</dt>
    <dd class="vcard"><span class="fn">Alex Russell</span>, <span class="org">Google</span>, &lt;<a class="email" href="mailto:slightlyoff@chromium.org">slightlyoff@chromium.org</a>&gt;</dd>
    <dd class="vcard"><span class="fn">Jungkee Song</span>, <span class="org">Samsung Electronics</span>, &lt;<a class="email" href="mailto:slightlyoff@chromium.org">jungkee.song@samsung.com</a>&gt;</dd>
  </dl>

  <p class="copyright">
    <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2014 <a href="http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>©</sup> (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href="http://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href="http://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>), All Rights Reserved. <abbr title="World Wide Web Consortium">W3C</abbr> <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply.
  </p>

  <hr>

  <h2 id="abstract">Abstract</h2>

  <p>This specification describes a method that enables applications to take advantage of persistent background processing, including hooks to enable bootstrapping of web applications while offline.</p>

  <p>The core of this system is an event-driven <a href="http://www.w3.org/TR/workers/">Web Worker</a>, which responds to events dispatched from documents and other sources. A system for managing installation, versions, and upgrades is provided.</p>

  <p>The service worker is a generic entry point for event-driven background processing in the Web Platform that is <a href="#extensibility">extensible by other specifications</a>.</p>

  <h2 id="status">Status of This Document</h2>

<p><em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at http://www.w3.org/TR/.</em></p>

<p>This document was published by the <a href="http://www.w3.org/2008/webapps/">Web Applications Working Group</a> as a Working Draft. If you wish to make comments regarding this document, please send them to <a href="mailto:public-webapps@w3.org">public-webapps@w3.org</a> (<a href="mailto:public-webapps-request@w3.org?subject=subscribe">subscribe</a>, <a href="http://lists.w3.org/Archives/Public/public-webapps/">archives</a>). All feedback is welcome.</p><p>Publication as a Working Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.</p>

<p>This document was produced by a group operating under the <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. <abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="http://www.w3.org/2004/01/pp-impl/42538/status" rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>.</p>

<p>This document is governed by the <a id="w3c_process_revision" href="http://www.w3.org/2014/Process-20140801/">1 August 2014 <abbr title="World Wide Web Consortium">W3C</abbr> Process Document</a>.</p>
</div>

<nav>
  <h2 id="toc">Table of Contents</h2>
  <ol>
    <li>
      <span class="marker">1</span>
      <a href="#introduction">Introduction</a>
      <ol>
        <li>
          <span class="marker">1.1</span>
          <a href="#about">About this Document</a>
        </li>
        <li>
          <span class="marker">1.2</span>
          <a href="#dependencies">Dependencies</a>
        </li>
        <li>
          <span class="marker">1.3</span>
          <a href="#motivations">Motivations</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">2</span>
      <a href="#model">Model</a>
      <ol>
        <li>
          <span class="marker">2.1</span>
          <a href="#service-worker-concept">Service Worker</a>
          <ol>
            <li>
              <span class="marker">2.1.1</span>
              <a href="#service-worker-lifetime">Lifetime</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">2.2</span>
          <a href="#service-worker-registration-concept">Service Worker Registration</a>
          <ol>
            <li>
              <span class="marker">2.2.1</span>
              <a href="#service-worker-registration-lifetime">Lifetime</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">2.3</span>
          <a href="#service-worker-client-concept">Service Worker Client</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">3</span>
      <a href="#document-context">Document Context</a>
      <ol>
        <li>
          <span class="marker">3.1</span>
          <a href="#service-worker-obj">ServiceWorker</a>
          <ol>
            <li>
              <span class="marker">3.1.1</span>
              <a href="#service-worker-url">scriptURL</a>
            </li>
            <li>
              <span class="marker">3.1.2</span>
              <a href="#service-worker-state">state</a>
            </li>
            <li>
              <span class="marker">3.1.3</span>
              <a href="#service-worker-event-handler">Event handler</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">3.2</span>
          <a href="#service-worker-registration-obj">ServiceWorkerRegistration</a>
          <ol>
            <li>
              <span class="marker">3.2.1</span>
              <a href="#navigator-service-worker-installing">installing</a>
            </li>
            <li>
              <span class="marker">3.2.2</span>
              <a href="#navigator-service-worker-waiting">waiting</a>
            </li>
            <li>
              <span class="marker">3.2.3</span>
              <a href="#navigator-service-worker-active">active</a>
            </li>
            <li>
              <span class="marker">3.2.4</span>
              <a href="#service-worker-registration-scope">scope</a>
            </li>
            <li>
              <span class="marker">3.2.5</span>
              <a href="#navigator-service-worker-unregister">unregister()</a>
            </li>
            <li>
              <span class="marker">3.2.6</span>
              <a href="#service-worker-registration-event-handler">Event handler</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">3.3</span>
          <a href="#navigator-service-worker">navigator.serviceWorker</a>
        </li>
        <li>
          <span class="marker">3.4</span>
          <a href="#service-worker-container">ServiceWorkerContainer</a>
          <ol>
            <li>
              <span class="marker">3.4.1</span>
              <a href="#navigator-service-worker-controller">controller</a>
            </li>
            <li>
              <span class="marker">3.4.2</span>
              <a href="#navigator-service-worker-ready">ready</a>
            </li>
            <li>
              <span class="marker">3.4.3</span>
              <a href="#navigator-service-worker-register">register(scriptURL, options)</a>
            </li>
            <li>
              <span class="marker">3.4.4</span>
              <a href="#navigator-service-worker-getRegistration">getRegistration(documentURL)</a>
            </li>
            <li>
              <span class="marker">3.4.5</span>
              <a href="#navigator-service-worker-getRegistrations">getRegistrations()</a>
            </li>
            <li>
              <span class="marker">3.4.6</span>
              <a href="#service-worker-container-event-handlers">Event handlers</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">3.5</span>
          <a href="#document-context-events">Events</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">4</span>
      <a href="#execution-context">Execution Context</a>
      <ol>
        <li>
          <span class="marker">4.1</span>
          <a href="#service-worker-global-scope">ServiceWorkerGlobalScope</a>
          <ol>
            <li>
              <span class="marker">4.1.1</span>
              <a href="#service-worker-global-scope-script-cache">scriptCache</a>
            </li>
            <li>
              <span class="marker">4.1.2</span>
              <a href="#service-worker-global-scope-caches">caches</a>
            </li>
            <li>
              <span class="marker">4.1.3</span>
              <a href="#service-worker-global-scope-clients">clients</a>
            </li>
            <li>
              <span class="marker">4.1.4</span>
              <a href="#service-worker-global-scope-scope">scope</a>
            </li>
            <li>
              <span class="marker">4.1.5</span>
              <a href="#service-worker-global-scope-update">update()</a>
            </li>
            <li>
              <span class="marker">4.1.6</span>
              <a href="#service-worker-global-scope-unregister">unregister()</a>
            </li>
            <li>
              <span class="marker">4.1.7</span>
              <a href="#service-worker-global-scope-skipwaiting">skipWaiting()</a>
            </li>
            <li>
              <span class="marker">4.1.8</span>
              <a href="#service-worker-global-scope-event-handlers">Event handlers</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">4.2</span>
          <a href="#service-worker-client">ServiceWorkerClient</a>
        </li>
        <li>
          <span class="marker">4.3</span>
          <a href="#service-worker-clients">ServiceWorkerClients</a>
          <ol>
            <li>
              <span class="marker">4.3.1</span>
              <a href="#get-all-method">getAll(options)</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">4.4</span>
          <a href="#cache-objects">Caches</a>
          <ol>
            <li>
              <span class="marker">4.4.1</span>
              <a href="#cache-lifetimes">Understanding Cache Lifetimes</a>
            </li>
            <li>
              <span class="marker">4.4.2</span>
              <a href="#cache">Cache</a>
              <ol>
                <li>
                  <span class="marker">4.4.2.1</span>
                  <a href="#cache-match">match(request, options)</a>
                </li>
                <li>
                  <span class="marker">4.4.2.2</span>
                  <a href="#cache-matchall">matchAll(request, options)</a>
                </li>
                <li>
                  <span class="marker">4.4.2.3</span>
                  <a href="#cache-add">add(request)</a>
                </li>
                <li>
                  <span class="marker">4.4.2.4</span>
                  <a href="#cache-addAll">addAll(requests)</a>
                </li>
                <li>
                  <span class="marker">4.4.2.5</span>
                  <a href="#cache-put">put(request, response)</a>
                </li>
                <li>
                  <span class="marker">4.4.2.6</span>
                  <a href="#cache-delete">delete(request, options)</a>
                </li>
                <li>
                  <span class="marker">4.4.2.7</span>
                  <a href="#cache-keys">keys(request, options)</a>
                </li>
              </ol>
            </li>
            <li>
              <span class="marker">4.4.3</span>
              <a href="#cache-storage">CacheStorage</a>
              <ol>
                <li>
                  <span class="marker">4.4.3.1</span>
                  <a href="#cache-storage-match">match(request, options)</a>
                </li>
                <li>
                  <span class="marker">4.4.3.2</span>
                  <a href="#cache-storage-has">has(cacheName)</a>
                </li>
                <li>
                  <span class="marker">4.4.3.3</span>
                  <a href="#cache-storage-open">open(cacheName)</a>
                </li>
                <li>
                  <span class="marker">4.4.3.4</span>
                  <a href="#cache-storage-delete">delete(cacheName)</a>
                </li>
                <li>
                  <span class="marker">4.4.3.5</span>
                  <a href="#cache-storage-keys">keys()</a>
                </li>
              </ol>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">4.5</span>
          <a href="#extendable-event">ExtendableEvent</a>
          <ol>
            <li>
              <span class="marker">4.5.1</span>
              <a href="#wait-until-method">event.waitUntil(f)</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">4.6</span>
          <a href="#install-event-section">InstallEvent</a>
        </li>
        <li>
          <span class="marker">4.7</span>
          <a href="#fetch-event-section">FetchEvent</a>
          <ol>
            <li>
              <span class="marker">4.7.1</span>
              <a href="#respond-with-method">event.respondWith(r)</a>
            </li>
            <li>
              <span class="marker">4.7.2</span>
              <a href="#default-method">event.default()</a>
            </li>
            <li>
              <span class="marker">4.7.3</span>
              <a href="#is-reload-attribute">event.isReload</a>
            </li>
          </ol>
        </li>
        <li>
          <span class="marker">4.8</span>
          <a href="#execution-context-events">Events</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">5</span>
      <a href="#security-considerations">Security Considerations</a>
      <ol>
        <li>
          <span class="marker">5.1</span>
          <a href="#origin-relativity">Origin Relativity</a>
        </li>
        <li>
          <span class="marker">5.2</span>
          <a href="#cross-origin-resources">Cross-Origin Resources &amp; CORS</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">6</span>
      <a href="#storage-considerations">Storage Considerations</a>
    </li>
    <li>
      <span class="marker">7</span>
      <a href="#extensibility">Extensibility</a>
      <ol>
        <li>
          <span class="marker">7.1</span>
          <a href="#extension-to-service-worker-registration">Define API bound to Service Worker Registration</a>
        </li>
        <li>
          <span class="marker">7.2</span>
          <a href="#extension-to-extendable-event">Define Functional Event</a>
        </li>
        <li>
          <span class="marker">7.3</span>
          <a href="#extension-to-service-worker-global-scope">Define Event Handler</a>
        </li>
        <li>
          <span class="marker">7.4</span>
          <a href="#extension-to-service-worker-global-scope">Request Functional Event Dispatch</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">8</span>
      <a href="#algorithms">Appendix A: Algorithms</a>
      <ol>
        <li>
          <span class="marker">8.1</span>
          <a href="#register-algorithm">Register</a>
        </li>
        <li>
          <span class="marker">8.2</span>
          <a href="#update-algorithm">Update</a>
        </li>
        <li>
          <span class="marker">8.3</span>
          <a href="#soft-update-algorithm">Soft Update</a>
        </li>
        <li>
          <span class="marker">8.4</span>
          <a href="#installation-algorithm">Install</a>
        </li>
        <li>
          <span class="marker">8.5</span>
          <a href="#activation-algorithm">Activate</a>
        </li>
        <li>
          <span class="marker">8.6</span>
          <a href="#on-fetch-request-algorithm">Handle Fetch</a>
        </li>
        <li>
          <span class="marker">8.7</span>
          <a href="#handle-functional-event-algorithm">Handle Functional Event</a>
        </li>
        <li>
          <span class="marker">8.8</span>
          <a href="#handle-functional-event-on-scheduled-task-algorithm">Handle Functional Event On Scheduled Task</a>
        </li>
        <li>
          <span class="marker">8.9</span>
          <a href="#on-document-unload-algorithm">Handle Document Unload</a>
        </li>
        <li>
          <span class="marker">8.10</span>
          <a href="#unregister-algorithm">Unregister</a>
        </li>
        <li>
          <span class="marker">8.11</span>
          <a href="#set-registration-algorithm">Set Registration</a>
        </li>
        <li>
          <span class="marker">8.12</span>
          <a href="#clear-registration-algorithm">Clear Registration</a>
        </li>
        <li>
          <span class="marker">8.13</span>
          <a href="#update-state-algorithm">Update State</a>
        </li>
        <li>
          <span class="marker">8.14</span>
          <a href="#scope-match-algorithm">Match Scope</a>
        </li>
        <li>
          <span class="marker">8.15</span>
          <a href="#get-registration-algorithm">Get Registration</a>
        </li>
        <li>
          <span class="marker">8.16</span>
          <a href="#get-newest-worker-algorithm">Get Newest Worker</a>
        </li>
        <li>
          <span class="marker">8.17</span>
          <a href="#query-cache-algorithm">Query Cache</a>
        </li>
        <li>
          <span class="marker">8.18</span>
          <a href="#batch-cache-operations-algorithm">Batch Cache Operations</a>
        </li>
      </ol>
    </li>
    <li>
      <span class="marker">9</span>
      <a href="#acknowledgements">Acknowledgements</a>
    </li>
  </ol>
</nav>

<section id="introduction"><header><span class="section-number">1</span> <h1 data-bookmark-label="1 Introduction">Introduction</h1><span class="anchor"><a style="text-decoration: none;" href="#introduction">¶</a></span></header>


  <section id="about"><header><span class="section-number">1.1</span> <h1 data-bookmark-label="1.1 About this Document">About this Document</h1><span class="anchor"><a style="text-decoration: none;" href="#about">¶</a></span></header>


    <p id="about.1">All diagrams, examples, notes, are non-normative, as well as sections explicitly marked as non-normative. Everything else in this specification is normative.</p>

    <p id="about.2">The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in <a href="http://dev.w3.org/2006/xbl2/#refsRFC2119">RFC2119</a>. For readability, these words do not appear in all uppercase letters in this specification.</p>

    <p id="about.3">Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as <a href="http://en.wikipedia.org/wiki/Algorithm">algorithm</a>. The algorithms are defined in terms of processing equivalence. The <dfn id="dfn-processing-equivalence">processing equivalence</dfn> is a constraint imposed on the algorithm implementers, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.</p>
  </section>

  <section id="dependencies"><header><span class="section-number">1.2</span> <h1 data-bookmark-label="1.2 Dependencies">Dependencies</h1><span class="anchor"><a style="text-decoration: none;" href="#dependencies">¶</a></span></header>


    <p id="dependencies.1">This document relies on the following specifications:</p>

    <ul>
      <li><a href="http://www.w3.org/TR/workers/">Web Workers</a></li>
      <li><a href="https://fetch.spec.whatwg.org/">Fetch Living Standard</a></li>
      <li><a href="https://dom.spec.whatwg.org/">DOM Living Standard</a></li>
      <li><a href="https://html.spec.whatwg.org/multipage/">HTML Living Standard</a></li>
      <li><a href="http://ecma-international.org/ecma-262/5.1/">ECMAScript Language Specification</a></li>
      <li><a href="http://www.w3.org/TR/WebIDL/">Web IDL</a></li>
      <li><a href="http://www.w3.org/TR/quota-api/">Quota Management API</a></li>
      <li><a href="http://www.w3.org/TR/notifications/">Web Notifications</a></li>
      <li><a href="http://tools.ietf.org/html/rfc6454">The Web Origin Concept</a></li>
      <li><a href="https://url.spec.whatwg.org/">URL Living Standard</a></li>
      <li><a href="http://tools.ietf.org/html/rfc2616">Hypertext Transfer Protocol -- HTTP/1.1</a></li>
      <li><a href="http://www.w3.org/TR/mixed-content/">Mixed Content</a></li>
      <li><a href="http://www.w3.org/2001/tag/doc/promises-guide">Writing Promise-Using Specifications</a></li>
    </ul>
  </section>

  <section id="motivations"><header><span class="section-number">1.3</span> <h1 data-bookmark-label="1.3 Motivations">Motivations</h1><span class="anchor"><a style="text-decoration: none;" href="#motivations">¶</a></span></header>


    <p id="motivations.1">Web Applications traditionally assume that the network is reachable. This assumption pervades the platform. HTML documents are loaded over HTTP and traditionally fetch all of their sub-resources via subsequent HTTP requests. This places web content at a disadvantage versus other technology stacks.</p>

    <p id="motivations.2">The <a href="#dfn-service-worker">service worker</a> is designed first to redress this balance by providing a Web Worker context, which can be started by a runtime when navigations are about to occur. This event-driven worker is registered against an origin and a path (or pattern), meaning it can be consulted when navigations occur to that location. Events that correspond to network requests are dispatched to the worker and the responses generated by the worker may over-ride default network stack behavior. This puts the <a href="#dfn-service-worker">service worker</a>, conceptually, between the network and a document renderer, allowing the <a href="#dfn-service-worker">service worker</a> to provide content for documents, even while offline.</p>

    <p id="motivations.3">Web developers familiar with previous attempts to solve the offline problem have reported a deficit of flexibility in those solutions. As a result, the <a href="#dfn-service-worker">service worker</a> is highly procedural, providing a maximum of flexibility at the price of additional complexity for developers. Part of this complexity arises from the need to keep <a href="#dfn-service-worker">service workers</a> responsive in the face of a single-threaded execution model. As a result, APIs exposed by <a href="#dfn-service-worker">service workers</a> are almost entirely asynchronous, a pattern familiar in other JavaScript contexts but accentuated here by the need to avoid blocking document and resource loading.</p>

    <p id="motivations.4">Developers using the <a href="https://html.spec.whatwg.org/multipage/browsers.html#offline">HTML5 Application Cache</a> have also <a href="http://alistapart.com/article/application-cache-is-a-douchebag">reported that several attributes</a> of the design contribute to <a href="http://alistapart.com/article/application-cache-is-a-douchebag/index.html#section6">unrecoverable errors</a>. A key design principle of the <a href="#dfn-service-worker">service worker</a> is that errors should <em>always</em> be recoverable. Many details of the update process of <a href="#dfn-service-worker">service workers</a> are designed to avoid these hazards.</p>

    <p id="motivations.5"><a href="#dfn-service-worker">service workers</a> are started and kept alive by their relationship to events, not documents. This design borrows heavily from developer and vendor experience with <a href="http://www.w3.org/TR/workers/#sharedworker">Shared Workers</a> and <a href="https://developer.chrome.com/extensions/background_pages">Chrome Background Pages</a>. A key lesson from these systems is the necessity to time-limit the execution of background processing contexts, both to conserve resources and to ensure that background context loss and restart is top-of-mind for developers. As a result, <a href="#dfn-service-worker">service workers</a> bear more than a passing resemblance to <a href="https://developer.chrome.com/extensions/event_pages">Chrome Event Pages</a>, the successor to Background Pages. <a href="#dfn-service-worker">service workers</a> may be started by user agents <em>without an attached document</em> and may be killed by the user agent at nearly any time. Conceptually, <a href="#dfn-service-worker">service workers</a> can be thought of as Shared Workers that can start, process events, and die without ever handling messages from documents. Developers are advised to keep in mind that <a href="#dfn-service-worker">service workers</a> may be started and killed many times a second.</p>

    <p id="motivations.6"><a href="#dfn-service-worker">service workers</a> are generic, event-driven, time-limited script contexts that run at an origin. These properties make them natural endpoints for a range of runtime services that may outlive the context of a particular document, e.g. handling push notifications, background data synchronization, responding to resource requests from other origins, or receiving centralized updates to expensive-to-calculate data (e.g., geolocation or gyroscope).</p>
  </section>
</section>

<section id="model"><header><span class="section-number">2</span> <h1 data-bookmark-label="2 Model">Model</h1><span class="anchor"><a style="text-decoration: none;" href="#model">¶</a></span></header>


  <section id="service-worker-concept"><header><span class="section-number">2.1</span> <h1 data-bookmark-label="2.1 Service Worker">Service Worker</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-concept">¶</a></span></header>

    <p id="service-worker-concept.1">A <dfn id="dfn-service-worker">service worker</dfn> is a type of <a href="http://www.w3.org/TR/workers/">web worker</a>. A <a href="#dfn-service-worker">service worker</a> executes in the registering <a href="#dfn-service-worker-client">service worker client</a>'s <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>.</p>
    <p id="service-worker-concept.2">A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-state">state</dfn>, which is one of <em>parsed</em>, <em>installing</em>, <em>installed</em>, <em>activating</em>, <em>activated</em>, and <em>redundant</em>. (Initially <em>parsed</em>).</p>
    <p id="service-worker-concept.3">A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-script-url">script url</dfn> (a <a href="https://url.spec.whatwg.org/#concept-url">URL</a>).</p>
    <p id="service-worker-concept.4">A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-containing-service-worker-registration">containing service worker registration</dfn> (a <a href="#dfn-service-worker-registration">service worker registration</a>), which contains itself.</p>
    <p id="service-worker-concept.5">A <a href="#dfn-service-worker">service worker</a> is dispatched a set of <dfn id="dfn-lifecycle-events">lifecycle events</dfn>, <a href="#service-worker-global-scope-install-event">install</a> and <a href="#service-worker-global-scope-activate-event">activate</a>, and <dfn id="dfn-functional-events">functional events</dfn> including <a href="#service-worker-global-scope-fetch-event">fetch</a>.</p>
    <p id="service-worker-concept.6">A <a href="#dfn-service-worker">service worker</a> has an associated <dfn id="dfn-skip-waiting-flag">skip waiting flag</dfn>. Unless stated otherwise it is unset.</p>

    <section id="service-worker-lifetime"><header><span class="section-number">2.1.1</span> <h1 data-bookmark-label="2.1.1 Lifetime">Lifetime</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-lifetime">¶</a></span></header>

    <p id="service-worker-lifetime.1">The lifetime of a <a href="#dfn-service-worker">service worker</a> is tied to the execution lifetime of events, not references held by <a href="#dfn-service-worker-client">service worker clients</a> to the <code><a href="#service-worker-interface">ServiceWorker</a></code> object. The user agent may <a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">terminate</a> <a href="#dfn-service-worker">service workers</a> at any time it has no event to handle.</p>
    </section>
  </section>

  <section id="service-worker-registration-concept"><header><span class="section-number">2.2</span> <h1 data-bookmark-label="2.2 Service Worker Registration">Service Worker Registration</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-registration-concept">¶</a></span></header>

    <p id="service-worker-registration-concept.1">A <dfn id="dfn-service-worker-registration">service worker registration</dfn> is a tuple of a <a href="#dfn-scope-url">scope url</a> and a set of <a href="#dfn-service-worker">service workers</a>, an <a href="#dfn-installing-worker">installing worker</a>, a <a href="#dfn-waiting-worker">waiting worker</a>, and an <a href="#dfn-active-worker">active worker</a>. User agents may enable many <a href="#dfn-service-worker-registration">service worker registrations</a> at a single origin so long as the <a href="#dfn-scope-url">scope url</a> of the <a href="#dfn-service-worker-registration">service worker registration</a> differs. <a href="#dfn-service-worker-registration">service worker registration</a> of an identical <a href="#dfn-scope-url">scope url</a> when one already exists in the user agent causes the existing <a href="#dfn-service-worker-registration">service worker registration</a> to be replaced.</p>
    <p id="service-worker-registration-concept.2">A <a href="#dfn-service-worker-registration">service worker registration</a> has an associated <dfn id="dfn-scope-url">scope url</dfn> (a <a href="https://url.spec.whatwg.org/#concept-url">URL</a>).</p>
    <p id="service-worker-registration-concept.3">A <a href="#dfn-service-worker-registration">service worker registration</a> has an associated <dfn id="dfn-registration-script-url">registering script url</dfn> (a <a href="https://url.spec.whatwg.org/#concept-url">URL</a>).</p>
    <p id="service-worker-registration-concept.4">A <a href="#dfn-service-worker-registration">service worker registration</a> has an associated <dfn id="dfn-installing-worker">installing worker</dfn> (a <a href="#dfn-service-worker">service worker</a>) whose <a href="#dfn-state">state</a> is <em>installing</em>. It is initially set to null.</p>
    <p id="service-worker-registration-concept.5">A <a href="#dfn-service-worker-registration">service worker registration</a> has an associated <dfn id="dfn-waiting-worker">waiting worker</dfn> (a <a href="#dfn-service-worker">service worker</a>) whose <a href="#dfn-state">state</a> is <em>installed</em>. It is initially set to null.</p>
    <p id="service-worker-registration-concept.6">A <a href="#dfn-service-worker-registration">service worker registration</a> has an associated <dfn id="dfn-active-worker">active worker</dfn> (a <a href="#dfn-service-worker">service worker</a>) whose <a href="#dfn-state">state</a> is either <em>activating</em> or <em>activated</em>. It is initially set to null. An <a href="#dfn-active-worker">active worker</a> <dfn id="dfn-control">controls</dfn> a <a href="#dfn-service-worker-client">service worker client</a> if the <a href="#dfn-active-worker">active worker</a>'s <a href="#dfn-service-worker-registration">service worker registration</a>'s <a href="#dfn-scope-url">scope url</a> <a href="#scope-match-algorithm">matches</a> the <a href="#dfn-service-worker-client">service worker client</a>'s <a href="#dfn-client-url">client url</a> upon <a href="https://html.spec.whatwg.org/multipage/browsers.html#navigate">navigation</a>. When a <a href="#dfn-service-worker-client">service worker client</a> is <a href="#dfn-control">controlled</a> by an <a href="#dfn-active-worker">active worker</a>, it is considered the <a href="#dfn-service-worker-client">service worker client</a> is <dfn id="dfn-use">using</dfn> the <a href="#dfn-active-worker">active worker</a>'s <a href="#dfn-service-worker-registration">service worker registration</a>.</p>
    <p id="service-worker-registration-concept.7">A <a href="#dfn-service-worker-registration">service worker registration</a> has an associated <dfn id="dfn-uninstalling-flag">uninstalling flag</dfn>. It is initially unset.</p>

    <section id="service-worker-registration-lifetime"><header><span class="section-number">2.2.1</span> <h1 data-bookmark-label="2.2.1 Lifetime">Lifetime</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-registration-lifetime">¶</a></span></header>

    <p id="service-worker-registration-lifetime.1">The user agents must persistently keep a list of <a href="#register-algorithm">registered</a> <a href="#dfn-service-worker-registration">service worker registrations</a> unless otherwise they are explicitly <a href="#unregister-algorithm">unregistered</a>. The lifetime of <a href="#dfn-service-worker-registration">service worker registrations</a> is beyond that of the <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> objects which represent them within the lifetime of their corresponding <a href="#dfn-service-worker-client">service worker clients</a>. <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a> represents an internal map structure that stores the entries of the tuple of <a href="#dfn-service-worker-registration">service worker registration</a>'s <a href="#dfn-scope-url">scope url</a> and the corresponding <a href="#dfn-service-worker-registration">service worker registration</a>.</p>
    </section>
  </section>
  <section id="service-worker-client-concept"><header><span class="section-number">2.3</span> <h1 data-bookmark-label="2.3 Service Worker Client">Service Worker Client</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-client-concept">¶</a></span></header>

    <p id="service-worker-client-concept.1">A <dfn id="dfn-service-worker-client">service worker client</dfn> is either a <a href="https://html.spec.whatwg.org/multipage/browsers.html#concept-document-window">document</a> in a <a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context">browsing context</a> or a <a href="https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope">shared worker</a>, which is <a href="#dfn-control">controlled</a> by an <a href="#dfn-active-worker">active worker</a>. A <a href="#dfn-service-worker-client">service worker client</a> independently <a href="#scope-match-algorithm">selects</a> and <a href="#dfn-use">uses</a> a <a href="#dfn-service-worker">service worker</a> for its own loading and its subresources. Unless specified otherwise, a <a href="#dfn-service-worker-client">service worker client</a> is a <a href="https://html.spec.whatwg.org/multipage/browsers.html#concept-document-window">document</a>.</p>
    <p id="service-worker-client-concept.2">A <a href="#dfn-service-worker-client">service worker client</a> has an associated <dfn id="dfn-client-service-worker-registration">service worker registration</dfn> (a <a href="#dfn-service-worker-registration">service worker registration</a>) it <a href="#dfn-use">uses</a>.</p>
    <p id="service-worker-client-concept.3">A <a href="#dfn-service-worker-client">service worker client</a> has an associated <dfn id="dfn-hidden-flag">hidden flag</dfn>. Initially set to false.</p>
    <p id="service-worker-client-concept.4">A <a href="#dfn-service-worker-client">service worker client</a> has an associated <dfn id="dfn-focused-flag">focused flag</dfn>. Initially set to false.</p>
    <p id="service-worker-client-concept.5">A <a href="#dfn-service-worker-client">service worker client</a> has an associated <dfn id="dfn-client-url">client url</dfn>, which is one of the <a href="https://html.spec.whatwg.org/#url">URL</a> of itself when it is a <a href="https://html.spec.whatwg.org/multipage/browsers.html#concept-document-window">document</a> of a <a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context">browsing context</a> and <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url">API base URL</a> when it is a <a href="https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope">shared worker</a>.</p>
    <p id="service-worker-client-concept.6">A <a href="#dfn-service-worker-client">service worker client</a> has an associated <dfn id="dfn-frame-type">frame type</dfn>, which is one of the values of <a href="https://fetch.spec.whatwg.org/#concept-request-context-frame-type">context frame type</a>.</p>

    <!--p>A <a href="#dfn-service-worker-client">service worker client</a> has an associated <dfn id="dfn-controller">controller</dfn> (an <a href="#dfn-active-worker">active worker</a>) which currently <a href="#dfn-control">controls</a> it. It is initially set to null.</p-->
  </section>
</section>

<section id="document-context"><header><span class="section-number">3</span> <h1 data-bookmark-label="3 Document Context">Document Context</h1><span class="anchor"><a style="text-decoration: none;" href="#document-context">¶</a></span></header>


  <p id="document-context.1">Example: Bootstrapping with a ServiceWorker</p>

<pre><code>// scope defaults to "/"
navigator.serviceWorker.register("/assets/v1/serviceworker.js").then(
  function(registration) {
    console.log("success!");
    if (registration.installing) {
      registration.installing.postMessage("Howdy from your installing page.");
    }
  },
  function(why) {
    console.error("Installing the worker failed!:", why);
  });</code></pre>

  <section id="service-worker-obj"><header><span class="section-number">3.1</span> <h1 data-bookmark-label="3.1 ServiceWorker"><code>ServiceWorker</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-obj">¶</a></span></header>


    <p id="service-worker-obj.1"></p>
<pre><code>[Exposed=(Window,ServiceWorker)]
interface <dfn id="service-worker-interface" title="ServiceWorker">ServiceWorker</dfn> : <a href="http://www.w3.org/TR/workers/#worker">Worker</a> {
  readonly attribute <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <a href="#service-worker-url-attribute">scriptURL</a>;
  readonly attribute <a href="#service-worker-state-enum">ServiceWorkerState</a> <a href="#service-worker-state-attribute">state</a>;

  // event
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-onstatechange-attribute">onstatechange</a>;

  // terminate() method inherited from Worker <a href="#service-worker-terminate-method">should not be accessible</a>.
};

enum <dfn id="service-worker-state-enum" title="State">ServiceWorkerState</dfn> {
  "installing",
  "installed",
  "activating",
  "activated",
  "redundant"
};</code></pre>

    <p id="service-worker-obj.2">A <code><a href="#service-worker-interface">ServiceWorker</a></code> object represents a <a href="#dfn-service-worker">service worker</a>. Each <code><a href="#service-worker-interface">ServiceWorker</a></code> object is associated with a <a href="#dfn-service-worker">service worker</a>. Multiple separate objects implementing the <code><a href="#service-worker-interface">ServiceWorker</a></code> interface across <a href="https://html.spec.whatwg.org/multipage/webappapis.html#document-environment">document environments</a> and <a href="https://html.spec.whatwg.org/multipage/webappapis.html#worker-environment">service worker environments</a> can all be associated with the same <a href="#dfn-service-worker">service worker</a> simultaneously.</p>

    <p id="service-worker-obj.3">A <code><a href="#service-worker-interface">ServiceWorker</a></code> object has an associated <code><a href="#service-worker-state-enum">ServiceWorkerState</a></code> object which is itself associated with <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-state">state</a>.</p>

    <p id="service-worker-terminate-method"><a id="service-worker-obj.4"></a>The <code><a href="http://www.w3.org/TR/workers/#dom-worker-terminate">terminate()</a></code> method inherited from <code><a href="http://www.w3.org/TR/workers/#worker">Worker</a></code>, when called on the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>, should throw an "<code><a href="http://heycam.github.io/webidl/#invalidaccesserror">InvalidAccessError</a></code>" exception.</p>

    <p id="service-worker-postmessage-method"><a id="service-worker-obj.5"></a>The <code><a href="https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage">postMessage(<var>message</var>, <var>transfer</var>)</a></code> method inherited from <code><a href="http://www.w3.org/TR/workers/#worker">Worker</a></code>, when called on the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>, should throw an "<code><a href="http://heycam.github.io/webidl/#invalidstateerror">InvalidStateError</a></code>" exception if the <a href="#service-worker-state-attribute">state</a> attribute of the <a href="https://dom.spec.whatwg.org/#context-object">context object</a> is "<code>redundant</code>". Otherwise, it must run <a href="https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage">as defined</a> on the <a href="https://html.spec.whatwg.org/multipage/workers.html#worker">Worker</a> interface.</p>

    <section id="service-worker-url"><header><span class="section-number">3.1.1</span> <h1 data-bookmark-label="3.1.1 scriptURL"><code>scriptURL</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-url">¶</a></span></header>


      <p id="service-worker-url.1">The <dfn id="service-worker-url-attribute"><code>scriptURL</code></dfn> attribute must return <a href="#dfn-service-worker">service worker</a>'s <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <a href="#dfn-script-url">script url</a>.</p>

      <p id="service-worker-url.2">For example, consider a document created by a navigation to <code>https://example.com/app.html</code> which <a href="#on-fetch-request-algorithm">matches</a> via the following registration call which has been previously executed:</p>

<pre><code>// Script on the page https://example.com/app.html
navigator.serviceWorker.register("/service_worker.js", { scope: "/" });</code></pre>

      <p id="service-worker-url.3">The value of <code>navigator.serviceWorker.controller.scriptURL</code> will be "<code>https://example.com/service_worker.js</code>".</p>
    </section>

    <section id="service-worker-state"><header><span class="section-number">3.1.2</span> <h1 data-bookmark-label="3.1.2 state"><code>state</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-state">¶</a></span></header>


      <p id="service-worker-state.1">The <dfn id="service-worker-state-attribute"><code>state</code></dfn> attribute must return the value (in <a href="#service-worker-state-enum">ServiceWorkerState</a> enumeration) corresponding to the first matching statement, switching on <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-state">state</a>:</p>

      <dl>
        <dt><em>installing</em></dt>
        <dd>"<code>installing</code>"
        <p class="note">The <a href="#dfn-service-worker">service worker</a> in this state is considered an <a href="#dfn-installing-worker">installing worker</a>. During this state, <code><a href="#extendable-event-waituntil-method">event.waitUntil(<var>f</var>)</a></code> can be called inside the <code><a href="#service-worker-global-scope-oninstall-attribute">oninstall</a></code> <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a> to extend the life of the <a href="#dfn-installing-worker">installing worker</a> until the passed <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolves successfully. This is primarily used to ensure that the <a href="#dfn-service-worker">service worker</a> is not active until all of the core caches are populated.</p></dd>

        <dt><em>installed</em></dt>
        <dd>"<code>installed</code>"
        <p class="note">The <a href="#dfn-service-worker">service worker</a> in this state is considered a <a href="#dfn-waiting-worker">waiting worker</a>.</p></dd>

        <dt><em>activating</em></dt>
        <dd>"<code>activating</code>"
        <p class="note">The <a href="#dfn-service-worker">service worker</a> in this state is considered an <a href="#dfn-active-worker">active worker</a>. During this state, <code><a href="#extendable-event-waituntil-method">event.waitUntil(<var>f</var>)</a></code> can be called inside the <code><a href="#service-worker-global-scope-onactivate-attribute">onactivate</a></code> <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a> to extend the life of the <a href="#dfn-active-worker">active worker</a> until the passed <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolves successfully. No <a href="#dfn-functional-events">functional events</a> are dispatched until the state becomes <em>activated</em>.</p></dd>

        <dt><em>activated</em></dt>
        <dd>"<code>activated</code>"
        <p class="note">The <a href="#dfn-service-worker">service worker</a> in this state is considered an <a href="#dfn-active-worker">active worker</a> ready to handle <a href="#dfn-functional-events">functional events</a>.</p></dd>

        <dt><em>redundant</em></dt>
        <dd>"<code>redundant</code>"
        <p class="note">A new <a href="#dfn-service-worker">service worker</a> is replacing the current <a href="#dfn-service-worker">service worker</a>, or the current <a href="#dfn-service-worker">service worker</a> is being discarded due to an install failure.</p></dd>
      </dl>
    </section>

    <section id="service-worker-event-handler"><header><span class="section-number">3.1.3</span> <h1 data-bookmark-label="3.1.3 Event handler">Event handler</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-event-handler">¶</a></span></header>


      <p id="service-worker-event-handler.1">The following is the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a> (and its corresponding <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event type</a>) that must be supported, as <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes">event handler IDL attributes</a>, by all objects implementing <code><a href="#service-worker-interface">ServiceWorker</a></code> interface:</p>

      <table>
        <thead>
          <tr>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a></th>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event type</a></th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><dfn id="service-worker-onstatechange-attribute"><code>onstatechange</code></dfn></td>
            <td><code><a href="#service-worker-statechange-event">statechange</a></code></td>
          </tr>
        </tbody>
      </table>
    </section>
  </section>

  <section id="service-worker-registration-obj"><header><span class="section-number">3.2</span> <h1 data-bookmark-label="3.2 ServiceWorkerRegistration"><code>ServiceWorkerRegistration</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-registration-obj">¶</a></span></header>


<pre><code>[Exposed=Window]
interface <dfn id="service-worker-registration-interface" title="ServiceWorkerRegistration">ServiceWorkerRegistration</dfn> : <a href="https://dom.spec.whatwg.org/#eventtarget">EventTarget</a> {
  [<a href="http://heycam.github.io/webidl/#Unforgeable">Unforgeable</a>] readonly attribute <a href="#service-worker-interface">ServiceWorker</a>? <a href="#service-worker-registration-installing-attribute">installing</a>;
  [<a href="http://heycam.github.io/webidl/#Unforgeable">Unforgeable</a>] readonly attribute <a href="#service-worker-interface">ServiceWorker</a>? <a href="#service-worker-registration-waiting-attribute">waiting</a>;
  [<a href="http://heycam.github.io/webidl/#Unforgeable">Unforgeable</a>] readonly attribute <a href="#service-worker-interface">ServiceWorker</a>? <a href="#service-worker-registration-active-attribute">active</a>;

  readonly attribute <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <a href="#service-worker-registration-scope-attribute">scope</a>;

  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;boolean&gt; <a href="#service-worker-registration-unregister-method">unregister</a>();

  // event
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-registration-onupdatefound-attribute">onupdatefound</a>;
};</code></pre>

    <p id="service-worker-registration-obj.1">A <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> object represents a <a href="#dfn-service-worker-registration">service worker registration</a>. Each <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> object is associated with a <a href="#dfn-service-worker-registration">service worker registration</a>. Multiple separate objects implementing the <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> interface across <a href="https://html.spec.whatwg.org/multipage/webappapis.html#document-environment">document environments</a> can all be associated with the same <a href="#dfn-service-worker-registration">service worker registration</a> simultaneously.</p>

    <section id="navigator-service-worker-installing"><header><span class="section-number">3.2.1</span> <h1 data-bookmark-label="3.2.1 installing"><code>installing</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-installing">¶</a></span></header>


      <p id="navigator-service-worker-installing.1"><dfn id="service-worker-registration-installing-attribute"><code>installing</code></dfn> attribute must return a <code><a href="#service-worker-interface">ServiceWorker</a></code> object that represents the <a href="#dfn-installing-worker">installing worker</a>.</p>
    </section>

    <section id="navigator-service-worker-waiting"><header><span class="section-number">3.2.2</span> <h1 data-bookmark-label="3.2.2 waiting"><code>waiting</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-waiting">¶</a></span></header>


      <p id="navigator-service-worker-waiting.1"><dfn id="service-worker-registration-waiting-attribute"><code>waiting</code></dfn> attribute must return a <code><a href="#service-worker-interface">ServiceWorker</a></code> object that represents the <a href="#dfn-waiting-worker">waiting worker</a>.</p>
    </section>

    <section id="navigator-service-worker-active"><header><span class="section-number">3.2.3</span> <h1 data-bookmark-label="3.2.3 active"><code>active</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-active">¶</a></span></header>


      <p id="navigator-service-worker-active.1"><dfn id="service-worker-registration-active-attribute"><code>active</code></dfn> attribute must return a <code><a href="#service-worker-interface">ServiceWorker</a></code> object that represents the <a href="#dfn-active-worker">active worker</a>.</p>
    </section>

    <section id="service-worker-registration-scope"><header><span class="section-number">3.2.4</span> <h1 data-bookmark-label="3.2.4 scope"><code>scope</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-registration-scope">¶</a></span></header>


      <p id="service-worker-registration-scope.1">The <dfn id="service-worker-registration-scope-attribute"><code>scope</code></dfn> attribute must return <a href="#dfn-service-worker-registration">service worker registration</a>'s <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <a href="#dfn-scope-url">scope url</a>.</p>

      <p id="service-worker-registration-scope.2">In the example in section 3.1.1, the value of <code>registration.scope</code>, obtained from <code>navigator.serviceWorker.ready.then(function(registration) { console.log(registration.scope); })</code> for example, will be "<code>https://example.com/</code>".</p>
    </section>

    <section id="navigator-service-worker-unregister"><header><span class="section-number">3.2.5</span> <h1 data-bookmark-label="3.2.5 unregister()"><code>unregister()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-unregister">¶</a></span></header>


      <p class="note" id="navigator-service-worker-unregister.1">The <code><a href="#service-worker-registration-unregister-method">unregister()</a></code> method unregisters the <a href="#dfn-service-worker-registration">service worker registration</a>. It is important to note that the currently <a href="#dfn-control">controlled</a> <a href="#dfn-service-worker-client">service worker client</a>'s <a href="#dfn-service-worker-registration">service worker registration</a> is effective until all the <a href="#dfn-service-worker-client">service worker clients</a> (including itself) using this <a href="#dfn-service-worker-registration">service worker registration</a> unload. That is, <code><a href="#service-worker-registration-unregister-method">unregister()</a></code> method only affects subsequent <a href="https://html.spec.whatwg.org/multipage/browsers.html#navigate">navigations</a>.</p>

      <p id="navigator-service-worker-unregister.2"><dfn id="service-worker-registration-unregister-method"><code>unregister()</code></dfn> method must return the result of running the <a href="#unregister-algorithm">Unregister</a> algorithm, or their <a href="#dfn-processing-equivalence">equivalent</a>, passing <var>document</var>, the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s associated <a href="https://dom.spec.whatwg.org/#concept-document">document</a>, and <var>scope</var>, the <a href="#dfn-scope-url">scope url</a> of the <a href="#dfn-service-worker-registration">service worker registration</a>, as the arguments.</p>
    </section>

    <section id="service-worker-registration-event-handler"><header><span class="section-number">3.2.6</span> <h1 data-bookmark-label="3.2.6 Event handler">Event handler</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-registration-event-handler">¶</a></span></header>


      <p id="service-worker-registration-event-handler.1">The following is the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a> (and its corresponding <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event type</a>) that must be supported, as <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes">event handler IDL attributes</a>, by all objects implementing <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> interface:</p>

      <table>
        <thead>
          <tr>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a></th>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event type</a></th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><dfn id="service-worker-registration-onupdatefound-attribute"><code>onupdatefound</code></dfn></td>
            <td><code><a href="#service-worker-container-updatefound-event">updatefound</a></code></td>
          </tr>
        </tbody>
      </table>
    </section>
  </section>

  <section id="navigator-service-worker"><header><span class="section-number">3.3</span> <h1 data-bookmark-label="3.3 navigator.serviceWorker"><code>navigator.serviceWorker</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker">¶</a></span></header>


<pre><code>partial interface <a href="https://html.spec.whatwg.org/multipage/webappapis.html#navigator">Navigator</a> {
  readonly attribute <a href="#service-worker-container-interface">ServiceWorkerContainer</a> <a href="#navigator-service-worker-attribute">serviceWorker</a>;
};</code></pre>

    <p id="navigator-service-worker.1">The <dfn id="navigator-service-worker-attribute"><code>serviceWorker</code></dfn> attribute of the <code><a href="https://html.spec.whatwg.org/multipage/webappapis.html#navigator">Navigator</a></code> interface must return a <code><a href="#service-worker-container-interface">ServiceWorkerContainer</a></code> object, which provides access to registration, removal, upgrade, and communication with <a href="#dfn-service-worker">service workers</a> for the <a href="https://html.spec.whatwg.org/multipage/browsers.html#concept-document-window">associated</a> <a href="https://dom.spec.whatwg.org/#concept-document">document</a>.</p>
    <p class="note" id="navigator-service-worker.2">Communication with these workers is provided via standard <a href="https://html.spec.whatwg.org/multipage/comms.html#web-messaging">HTML5 messaging APIs</a>, and <a href="http://www.w3.org/TR/workers/#dom-worker-postmessage">messaging occurs as per usual with Web Workers</a>.</p>
  </section>

  <section id="service-worker-container"><header><span class="section-number">3.4</span> <h1 data-bookmark-label="3.4 ServiceWorkerContainer"><code>ServiceWorkerContainer</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-container">¶</a></span></header>


<pre><code>[Exposed=Window]
interface <dfn id="service-worker-container-interface" title="ServiceWorkerContainer">ServiceWorkerContainer</dfn> : <a href="https://dom.spec.whatwg.org/#eventtarget">EventTarget</a> {
  [<a href="http://heycam.github.io/webidl/#Unforgeable">Unforgeable</a>] readonly attribute <a href="#service-worker-interface">ServiceWorker</a>? <a href="#service-worker-container-controller-attribute">controller</a>;
  readonly attribute <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="#service-worker-registration-interface">ServiceWorkerRegistration</a>&gt; <a href="#service-worker-container-ready-attribute">ready</a>;

  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="#service-worker-registration-interface">ServiceWorkerRegistration</a>&gt; <a href="#service-worker-container-register-method">register</a>(<a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <var>scriptURL</var>, optional <a href="#registration-option-list-dictionary">RegistrationOptions</a> <var>options</var>);

  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="#service-worker-registration-interface">ServiceWorkerRegistration</a>&gt; <a href="#service-worker-container-getregistration-method">getRegistration</a>(optional <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <var>documentURL</var> = "");
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;sequence&lt;<a href="#service-worker-registration-interface">ServiceWorkerRegistration</a>&gt;?&gt; <a href="#service-worker-container-getregistrations-method">getRegistrations</a>();


  // events
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-container-oncontrollerchange-attribute">oncontrollerchange</a>;
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-container-onerror-attribute">onerror</a>;
};

dictionary <dfn id="registration-option-list-dictionary" title="RegistrationOptions">RegistrationOptions</dfn> {
  <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> scope = "/";
};
</code></pre>

  <p id="service-worker-container.1">A <code><a href="#service-worker-container-interface" title="ServiceWorkerContainer">ServiceWorkerContainer</a></code>'s associated <a href="https://html.spec.whatwg.org/multipage/browsers.html#window">Window</a> is the associated <a href="https://html.spec.whatwg.org/multipage/browsers.html#window">Window</a> of the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#navigator">Navigator</a> object that the <code><a href="#service-worker-container-interface" title="ServiceWorkerContainer">ServiceWorkerContainer</a></code> is retrieved from. A <code><a href="#service-worker-container-interface" title="ServiceWorkerContainer">ServiceWorkerContainer</a></code>'s <span id="service-worker-container-associated-document">associated</span> <a href="https://html.spec.whatwg.org/multipage/dom.html#document">Document</a> is <a href="https://html.spec.whatwg.org/multipage/browsers.html#concept-document-window">the newest Document object</a> of its associated <a href="https://html.spec.whatwg.org/multipage/browsers.html#window">Window</a>.</p>

  <p id="service-worker-container.2">A <code><a href="#service-worker-container-interface" title="ServiceWorkerContainer">ServiceWorkerContainer</a></code> object has an associated <dfn id="dfn-ready-promise">ready promise</dfn> (a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>). It is initially set to null.</p>

  <section id="navigator-service-worker-controller"><header><span class="section-number">3.4.1</span> <h1 data-bookmark-label="3.4.1 controller"><code>controller</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-controller">¶</a></span></header>


    <p id="navigator-service-worker-controller.1"><dfn id="service-worker-container-controller-attribute"><code>controller</code></dfn> attribute must return a <code><a href="#service-worker-interface">ServiceWorker</a></code> object that represents the <a href="#dfn-active-worker">active worker</a> for the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#service-worker-container-associated-document">associated</a> <a href="https://dom.spec.whatwg.org/#concept-document">document</a>.</p>
    <p class="note" id="navigator-service-worker-controller.2"><code><a href="#service-worker-container-controller-attribute">navigator.serviceWorker.controller</a></code> returns <code>null</code> if the request is a force refresh (shift+refresh).</p>
  </section>
  <section id="navigator-service-worker-ready"><header><span class="section-number">3.4.2</span> <h1 data-bookmark-label="3.4.2 ready"><code>ready</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-ready">¶</a></span></header>


    <p id="navigator-service-worker-ready.1"><dfn id="service-worker-container-ready-attribute"><code>ready</code></dfn> attribute must return the result of running these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
    <div class="algorithm">
    <ol>
      <li>If the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#dfn-ready-promise">ready promise</a> is null, then:
        <ol>
          <li>Set the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#dfn-ready-promise">ready promise</a> to a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
        </ol>
      </li>
      <li>If the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#dfn-ready-promise">ready promise</a> is settled, then:
        <ol>
          <li>Return the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#dfn-ready-promise">ready promise</a>.</li>
        </ol>
      </li>
      <li>Let <var>registration</var> be null.</li>
      <li>Let <var>documentURL</var> be the result of running the <a href="https://url.spec.whatwg.org/#concept-url-serializer">URL serializer</a> on the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#service-worker-container-associated-document">associated</a> <a href="https://dom.spec.whatwg.org/#concept-document">document</a>'s URL.</li>
      <li>Run the following substeps in parallel:
        <ol>
          <li><em>CheckRegistration</em>: If the result of running <a href="#scope-match-algorithm">Match Scope</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>documentURL</var> as its argument is not null, then:
            <ol>
              <li>Set <var>registration</var> to the result value.</li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Wait until <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a> has a new entry.</li>
              <li>Jump to the step labeled <em>CheckRegistration</em>.</li>
            </ol>
          </li>
          <li>If <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> is null, then:
            <ol>
              <li>Wait until <var>registration</var> acquires an <a href="#dfn-active-worker">active worker</a>.</li>
            </ol>
            <p class="note">Implementers should consider this condition is met when the corresponding registration request gets to the step 1.8 of <a href="#activation-algorithm">Activate</a> algorithm.</p>
          </li>
          <li>Resolve <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#dfn-ready-promise">ready promise</a> with <var>registration</var>.</li>
        </ol>
      </li>
      <li>Return <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#dfn-ready-promise">ready promise</a>.</li>
    </ol>
    </div>
    <p class="note" id="navigator-service-worker-ready.2">The <code><a href="#service-worker-container-ready-attribute">ready</a></code> attribute is designed in a way that the returned <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> will never reject. Instead, it waits until the <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolves with a <a href="#dfn-service-worker-registration">service worker registration</a> that has an <a href="#dfn-active-worker">active worker</a>.</p>
  </section>

  <section id="navigator-service-worker-register"><header><span class="section-number">3.4.3</span> <h1 data-bookmark-label="3.4.3 register(scriptURL, options)"><code>register(<var>scriptURL</var>, <var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-register">¶</a></span></header>


    <p class="note" id="navigator-service-worker-register.1">The <code><a href="#service-worker-container-register-method">register(<var>scriptURL</var>, <var>options</var>)</a></code> method creates or updates a <a href="#dfn-service-worker-registration">service worker registration</a> for the given <a href="#dfn-scope-url">scope url</a>. If successful, a <a href="#dfn-service-worker-registration">service worker registration</a> ties the provided <var>script url</var> to a <a href="#dfn-scope-url">scope url</a>, which is subsequently used for <a href="#on-fetch-request-algorithm">navigation matching</a>.</p>

    <p id="navigator-service-worker-register.2"><dfn id="service-worker-container-register-method"><code>register(<var>scriptURL</var>, <var>options</var>)</code></dfn> method must return the result of running these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
    <div class="algorithm">
    <ol>
      <li>Let <var>p</var> be the result of running the <a href="#register-algorithm">Register</a> algorithm, or their <a href="#dfn-processing-equivalence">equivalent</a>, passing the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#service-worker-container-associated-document">associated</a> <a href="https://dom.spec.whatwg.org/#concept-document">document</a> <var>document</var>, <var>scriptURL</var>, <var>options</var>.<var>scope</var>, and <a href="https://html.spec.whatwg.org/multipage/webappapis.html#entry-settings-object">entry settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url">API base URL</a> as the arguments.</li>
      <li>Return <var>p</var>.</li>
    </ol>
    </div>
  </section>

  <section id="navigator-service-worker-getRegistration"><header><span class="section-number">3.4.4</span> <h1 data-bookmark-label="3.4.4 getRegistration(documentURL)"><code>getRegistration(<var>documentURL</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-getRegistration">¶</a></span></header>


    <p id="navigator-service-worker-getRegistration.1"><dfn id="service-worker-container-getregistration-method"><code>getRegistration(<var>documentURL</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

    <div class="algorithm">
    <ol>
      <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
      <li>Let <var>documentURL</var> be the result of running the <a href="https://url.spec.whatwg.org/#concept-url-parser">URL parser</a> on <var>documentURL</var> with <a href="https://html.spec.whatwg.org/multipage/webappapis.html#entry-settings-object">entry settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url">API base URL</a>.</li>
      <li>Set <var>documentURL</var> to the result of running the <a href="https://url.spec.whatwg.org/#concept-url-serializer">URL serializer</a> on <var>documentURL</var>.</li>
      <li>Run the following substeps in parallel:
        <ol>
          <li>If the <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> of <var>documentURL</var> does not match the document's <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>, then:
            <ol>
              <li>Reject <var>promise</var> with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>Let <var>registration</var> be the result of running <a href="#scope-match-algorithm">Match Scope</a> algorithm, or its equivalent, with <var>documentURL</var> as its argument.</li>
          <li>If <var>registration</var> is not null, then:
            <ol>
              <li>Resolve <var>promise</var> with a <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> object that represents <var>registration</var>.</li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Resolve <var>promise</var> with <code>undefined</code>.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Return <var>promise</var>.</li>
    </ol>
    </div>
  </section>

  <section id="navigator-service-worker-getRegistrations"><header><span class="section-number">3.4.5</span> <h1 data-bookmark-label="3.4.5 getRegistrations()"><code>getRegistrations()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#navigator-service-worker-getRegistrations">¶</a></span></header>


    <p id="navigator-service-worker-getRegistrations.1"><dfn id="service-worker-container-getregistrations-method"><code>getRegistrations()</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>


    <!--p>return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> that resolves with the array of the <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> objects.</p-->

    <div class="algorithm">
    <ol>
      <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
      <li>Run the following substeps in parallel:
        <ol>
          <li>Let <var>array</var> be an empty array.</li>
          <li>Let <var>origin</var> be the <a href="http://tools.ietf.org/html/rfc6454#section-6.1">unicode serialization</a> of the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#service-worker-container-associated-document">associated</a> <a href="https://dom.spec.whatwg.org/#concept-document">document</a>'s <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>.</li>
          <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a>:
            <ol>
              <li>If the <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> of <var>entry</var>.[[key]] matches <var>origin</var>, then:
                <ol>
                  <li>Add a <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> object associated with <var>entry</var>.[[value]] to the <var>array</var>.</li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Resolve <var>promise</var> with <var>array</var>.</li>
        </ol>
      </li>
      <li>Return <var>promise</var>.</li>
    </ol>
    </div>
  </section>

  <section id="service-worker-container-event-handlers"><header><span class="section-number">3.4.6</span> <h1 data-bookmark-label="3.4.6 Event handlers">Event handlers</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-container-event-handlers">¶</a></span></header>


      <p id="service-worker-container-event-handlers.1">The following are the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handlers</a> (and its corresponding <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event types</a>) that must be supported, as <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes">event handler IDL attributes</a>, by all objects implementing the <a href="#service-worker-container-interface">ServiceWorkerContainer</a> interface:</p>

      <table>
        <thead>
          <tr>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a></th>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event type</a></th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><dfn id="service-worker-container-oncontrollerchange-attribute"><code>oncontrollerchange</code></dfn></td>
            <td><code><a href="#service-worker-container-controllerchange-event">controllerchange</a></code></td>
          </tr>
          <tr>
            <td><dfn id="service-worker-container-onerror-attribute"><code>onerror</code></dfn></td>
            <td><code><a href="#service-worker-container-error-event">error</a></code></td>
          </tr>
        </tbody>
      </table>
    </section>
  </section>

  <section id="document-context-events"><header><span class="section-number">3.5</span> <h1 data-bookmark-label="3.5 Events">Events</h1><span class="anchor"><a style="text-decoration: none;" href="#document-context-events">¶</a></span></header>


    <p id="document-context-events.1">The following events are dispatched on <code><a href="#service-worker-interface">ServiceWorker</a></code> object:</p>

    <table>
      <thead>
        <tr>
          <th>Event name</th>
          <th>Interface</th>
          <th>Dispatched when…</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><dfn id="service-worker-statechange-event"><code>statechange</code></dfn></td>
          <td><code><a href="https://dom.spec.whatwg.org/#event">Event</a></code></td>
          <td>The <code><a href="#service-worker-state-attribute">state</a></code> attribute of the <code><a href="#service-worker-interface">ServiceWorker</a></code> object is changed.</td>
        </tr>
      </tbody>
    </table>

    <p id="document-context-events.2">The following events are dispatched on <code><a href="#service-worker-container-interface">ServiceWorkerContainer</a></code> object:</p>

    <table>
      <thead>
        <tr>
          <th>Event name</th>
          <th>Interface</th>
          <th>Dispatched when…</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><dfn id="service-worker-container-updatefound-event"><code>updatefound</code></dfn></td>
          <td><code><a href="https://dom.spec.whatwg.org/#event">Event</a></code></td>
          <td>A <a href="#dfn-service-worker-registration">service worker registration</a> acquires a new <a href="#dfn-installing-worker">installing worker</a> (See step 4.6 of the <a href="#installation-algorithm">Install</a> algorithm).</td>
        </tr>
        <tr>
          <td><dfn id="service-worker-container-controllerchange-event"><code>controllerchange</code></dfn></td>
          <td><code><a href="https://dom.spec.whatwg.org/#event">Event</a></code></td>
          <td>The <a href="#service-worker-container-associated-document">document</a>'s associated <a href="#dfn-client-service-worker-registration">service worker registration</a> acquires a new <a href="#dfn-active-worker">active worker</a>. (See step 1.9 of the <a href="#activation-algorithm">Activate</a> algorithm. The <a href="#dfn-skip-waiting-flag">skip waiting flag</a> of a <a href="#dfn-service-worker">service worker</a> causes <a href="#activation-algorithm">activation</a> of the <a href="#dfn-service-worker-registration">service worker registration</a> to occur while <a href="#service-worker-client-concept">clients</a> are <a href="#dfn-use">using</a> the <a href="#dfn-service-worker-registration">service worker registration</a>, <code><a href="#service-worker-container-controller-attribute">navigator.serviceWorker.controller</a></code> immediately reflects the <a href="#dfn-active-worker">active worker</a> as the <a href="#dfn-service-worker">service worker</a> that <a href="#dfn-control">controls</a> the document.)</td>
        </tr>
        <tr>
          <td><dfn id="service-worker-container-error-event"><code>error</code></dfn></td>
          <td><code><a href="https://html.spec.whatwg.org/multipage/webappapis.html#errorevent">ErrorEvent</a></code></td>
          <td>Any error occurred from the associated <a href="#dfn-service-worker">service workers</a>.</td>
        </tr>
      </tbody>
    </table>
  </section>
</section>

<section id="execution-context"><header><span class="section-number">4</span> <h1 data-bookmark-label="4 Execution Context">Execution Context</h1><span class="anchor"><a style="text-decoration: none;" href="#execution-context">¶</a></span></header>


  <p id="execution-context.1">Example: Serving Cached Resources</p>

<pre><code>// caching.js
this.addEventListener("install", function(e) {
  e.waitUntil(
    // Create a cache of resources.
    caches.create("shell-v1").then(function(cache) {
      // Begins the process of fetching them.
      // The coast is only clear when all the resources are ready.
      return cache.addAll([
        "/app.html",
        "/assets/v1/base.css",
        "/assets/v1/app.js",
        "/assets/v1/logo.png",
        "/assets/v1/intro_video.webm"
      ])
    })
  );
});

this.addEventListener("fetch", function(e) {
  // No "fetch" events are dispatched to the ServiceWorker until it
  // successfully installs.

  // All operations on caches are async, including matching URLs, so we use
  // promises heavily. e.respondWith() even takes promises to enable this:
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || e.default();
    }).catch(function() {
      return caches.match("/fallback.html");
    })
  );
});</code></pre>

  <section id="service-worker-global-scope"><header><span class="section-number">4.1</span> <h1 data-bookmark-label="4.1 ServiceWorkerGlobalScope"><code>ServiceWorkerGlobalScope</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope">¶</a></span></header>


<pre><code>[<a href="http://heycam.github.io/webidl/#Global">Global</a>=(Worker,ServiceWorker), Exposed=ServiceWorker]
interface <dfn id="service-worker-global-scope-interface" title="ServiceWorkerGlobalScope">ServiceWorkerGlobalScope</dfn> : <a href="http://www.w3.org/TR/workers/#workerglobalscope">WorkerGlobalScope</a> {
  readonly attribute <a href="#cache-interface">Cache</a> <a href="#service-worker-global-scope-script-cache-attribute">scriptCache</a>;
  readonly attribute <a href="#cache-storage-interface">CacheStorage</a> <a href="#service-worker-global-scope-caches-attribute">caches</a>;

  // A container for a list of ServiceWorkerClient objects that correspond to
  // browsing contexts (or shared workers) that are on the origin of this SW
  readonly attribute <a href="#service-worker-clients-interface">ServiceWorkerClients</a> <a href="#service-worker-global-scope-clients-attribute">clients</a>;
  [<a href="http://heycam.github.io/webidl/#Unforgeable">Unforgeable</a>] readonly attribute <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <a href="#service-worker-global-scope-caches-attribute">scope</a>;

  void <a href="#service-worker-global-scope-update-method">update</a>();
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;boolean&gt; <a href="#service-worker-global-scope-unregister-method">unregister</a>();
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;void&gt; <a href="#service-worker-global-scope-skipwaiting-method">skipWaiting</a>();

  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-global-scope-oninstall-attribute">oninstall</a>;
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-global-scope-onactivate-attribute">onactivate</a>;
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-global-scope-onfetch-attribute">onfetch</a>;
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-global-scope-onbeforeevicted-attribute">onbeforeevicted</a>;
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-global-scope-onevicted-attribute">onevicted</a>;

  // The event.source of these MessageEvents are instances of ServiceWorkerClient
  attribute <a href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler">EventHandler</a> <a href="#service-worker-global-scope-onmessage-attribute">onmessage</a>;

  // close() method inherited from WorkerGlobalScope <a href="#service-worker-global-scope-close-method">should not be accessible</a>.
};
</code></pre>

    <p id="service-worker-global-scope.1">A <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> object represents the global execution context of a <a href="#dfn-service-worker">service worker</a>.</p>
    <p class="note" id="service-worker-global-scope.2"><code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully <a href="#navigator-service-worker-register">registered</a>, a <a href="#dfn-service-worker">service worker</a> is started, kept alive and killed by their relationship to events, not <a href="#dfn-service-worker-client">service worker clients</a>. Any type of synchronous requests must not be initiated inside of a <a href="#dfn-service-worker">service worker</a>.</p>

    <p id="service-worker-global-scope-close-method" class="note"><a id="service-worker-global-scope.3"></a>The <code><a href="http://www.w3.org/TR/workers/#dom-workerglobalscope-close">close()</a></code> method inherited from <code><a href="http://www.w3.org/TR/workers/#workerglobalscope">WorkerGlobalScope</a></code>, when called on the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>, should throw an "<code><a href="http://heycam.github.io/webidl/#invalidaccesserror">InvalidAccessError</a></code>" exception.</p>

    <section id="service-worker-global-scope-script-cache"><header><span class="section-number">4.1.1</span> <h1 data-bookmark-label="4.1.1 scriptCache"><code>scriptCache</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-script-cache">¶</a></span></header>


      <p id="service-worker-global-scope-script-cache.1"><dfn id="service-worker-global-scope-script-cache-attribute"><code>scriptCache</code></dfn> must return a <code><a href="#cache-interface">Cache</a></code> object that represents the storage for scripts that are cached as part of the <a href="#dfn-service-worker">service worker</a> installation.</p>
    </section>
    <section id="service-worker-global-scope-caches"><header><span class="section-number">4.1.2</span> <h1 data-bookmark-label="4.1.2 caches"><code>caches</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-caches">¶</a></span></header>


      <p id="service-worker-global-scope-caches.1"><dfn id="service-worker-global-scope-caches-attribute"><code>caches</code></dfn> attribute must return the <code><a href="#cache-storage-interface">CacheStorage</a></code> object that is the global asynchronous map object for the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> execution context containing the <code><a href="#cache-interface">Cache</a></code> objects keyed by the name of the <code><a href="#cache-interface">Cache</a></code> objects. <code><a href="#cache-interface">Cache</a></code> objects are always enumerable via <code><a href="#service-worker-global-scope-caches-attribute">self.caches</a></code> in insertion order (per <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-objects">ECMAScript 6 Map objects</a>.)</p>
    </section>
    <section id="service-worker-global-scope-clients"><header><span class="section-number">4.1.3</span> <h1 data-bookmark-label="4.1.3 clients"><code>clients</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-clients">¶</a></span></header>


      <p id="service-worker-global-scope-clients.1"><dfn id="service-worker-global-scope-clients-attribute"><code>clients</code></dfn> attribute must return the <code><a href="#service-worker-clients-interface">ServiceWorkerClients</a></code> object.</p>
    </section>
    <section id="service-worker-global-scope-scope"><header><span class="section-number">4.1.4</span> <h1 data-bookmark-label="4.1.4 scope"><code>scope</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-scope">¶</a></span></header>


      The <dfn id="service-worker-global-scope-scope-attribute"><code>scope</code></dfn> attribute must return the <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <a href="#dfn-scope-url">scope url</a> of the <a href="#dfn-service-worker">service worker</a>'s associated <a href="#dfn-service-worker-registration">service worker registration</a>.<p id="service-worker-global-scope-scope.1"></p>
    </section>
    <section id="service-worker-global-scope-update"><header><span class="section-number">4.1.5</span> <h1 data-bookmark-label="4.1.5 update()"><code>update()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-update">¶</a></span></header>


      <p class="note" id="service-worker-global-scope-update.1"><code>update()</code> pings the server for an updated version of this script without consulting caches. This is conceptually the same operation that UA does maximum once per every 24 hours.</p>
      <p id="service-worker-global-scope-update.2"><dfn id="service-worker-global-scope-update-method"><code>update()</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
      <div class="algorithm">
      <ol>
        <li>Let <var>scope</var> be the <a href="#dfn-scope-url">scope url</a> of the <a href="#dfn-service-worker">service worker</a>'s associated <a href="#dfn-service-worker-registration">service worker registration</a>.</li>
        <li>Let <var>registration</var> be the result of running <a href="#get-registration-algorithm">Get Registration</a> algorithm passing <var>scope</var> as the argument.</li>
        <li>Invoke <a href="#soft-update-algorithm">Soft Update</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, passing <var>registration</var> as the argument.</li>
      </ol>
      </div>
    </section>
    <section id="service-worker-global-scope-unregister"><header><span class="section-number">4.1.6</span> <h1 data-bookmark-label="4.1.6 unregister()"><code>unregister()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-unregister">¶</a></span></header>


      <p class="note" id="service-worker-global-scope-unregister.1">The <code><a href="#service-worker-global-scope-unregister-method">unregister()</a></code> method unregisters its <a href="#dfn-containing-service-worker-registration">containing service worker registration</a>. It is important to note that this <a href="#dfn-service-worker-registration">service worker registration</a> is effective until all the documents (including itself) using this <a href="#dfn-service-worker-registration">service worker registration</a> unload. That is, <code><a href="#service-worker-global-scope-unregister-method">unregister()</a></code> method only affects subsequent <a href="https://html.spec.whatwg.org/multipage/browsers.html#navigate">navigations</a>.</p>

      <p id="service-worker-global-scope-unregister.2"><dfn id="service-worker-global-scope-unregister-method"><code>unregister()</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

      <div class="algorithm">
      <ol>
        <li>Let <var>scope</var> be the <a href="#dfn-scope-url">scope url</a> of the <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-containing-service-worker-registration">containing service worker registration</a>.</li>
        <li>Return the result of running <a href="#unregister-algorithm">Unregister</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, passing <var>document</var>, the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s associated <a href="https://dom.spec.whatwg.org/#concept-document">document</a>, and <var>scope</var> as the argument.</li>
      </ol>
      </div>
    </section>

    <section id="service-worker-global-scope-skipwaiting"><header><span class="section-number">4.1.7</span> <h1 data-bookmark-label="4.1.7 skipWaiting()"><code>skipWaiting()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-skipwaiting">¶</a></span></header>


      <p class="note" id="service-worker-global-scope-skipwaiting.1">The <code><a href="#service-worker-global-scope-skipwaiting-method">skipWaiting()</a></code> method allows this <a href="#dfn-service-worker">service worker</a> to progress from the <a href="#dfn-containing-service-worker-registration">registration</a>'s <a href="#dfn-waiting-worker">waiting</a> position to <a href="#dfn-active-worker">active</a> even while <a href="#service-worker-client-concept">clients</a> are <a href="#dfn-use">using</a> the <a href="#dfn-containing-service-worker-registration">registration</a>.</p>

      <p id="service-worker-global-scope-skipwaiting.2"><dfn id="service-worker-global-scope-skipwaiting-method"><code>skipWaiting()</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

      <div class="algorithm">
      <ol>
        <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
        <li>Run the following substeps in parallel:
          <ol>
            <li>Set <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-skip-waiting-flag">skip waiting flag</a></li>
            <li>If <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-state">state</a> is <em>installed</em>, then:
              <ol>
                <li>Run <a href="#activation-algorithm">Activate</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, passing <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-containing-service-worker-registration">registration</a> as the argument.</li>
              </ol>
            </li>
            <li>Resolve <var>promise</var> with undefined.</li>
          </ol>
        </li>
        <li>Return <var>promise</var>.</li>
      </ol>
      </div>
    </section>

    <section id="service-worker-global-scope-event-handlers"><header><span class="section-number">4.1.8</span> <h1 data-bookmark-label="4.1.8 Event handlers">Event handlers</h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-global-scope-event-handlers">¶</a></span></header>


      <p id="service-worker-global-scope-event-handlers.1">The following are the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handlers</a> (and its corresponding <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event types</a>) that must be supported, as <a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes">event handler IDL attributes</a>, by all objects implementing the <a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a> interface:</p>

      <table>
        <thead>
          <tr>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a></th>
            <th><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type">event handler event type</a></th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><dfn id="service-worker-global-scope-oninstall-attribute"><code>oninstall</code></dfn></td>
            <td><code><a href="#service-worker-global-scope-install-event">install</a></code></td>
          </tr>
          <tr>
            <td><dfn id="service-worker-global-scope-onactivate-attribute"><code>onactivate</code></dfn></td>
            <td><code><a href="#service-worker-global-scope-activate-event">activate</a></code></td>
          </tr>
          <tr>
            <td><dfn id="service-worker-global-scope-onfetch-attribute"><code>onfetch</code></dfn></td>
            <td><code><a href="#service-worker-global-scope-fetch-event">fetch</a></code></td>
          </tr>
          <tr>
            <td><dfn id="service-worker-global-scope-onbeforeevicted-attribute"><code>onbeforeevicted</code></dfn></td>
            <td><code><a href="#service-worker-global-scope-beforeevicted-event">beforeevicted</a></code></td>
          </tr>
          <tr>
            <td><dfn id="service-worker-global-scope-onevicted-attribute"><code>onevicted</code></dfn></td>
            <td><code><a href="#service-worker-global-scope-evicted-event">evicted</a></code></td>
          </tr>
          <tr>
            <td><dfn id="service-worker-global-scope-onmessage-attribute"><code>onmessage</code></dfn></td>
            <td><code><a href="https://html.spec.whatwg.org/multipage/indices.html#event-message">message</a></code></td>
          </tr>
        </tbody>
      </table>

      <p class="note" id="service-worker-global-scope-event-handlers.2">For <a href="#service-worker-global-scope-onmessage-attribute">onmessage </a><a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers">event handler</a>,<code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> objects act as if they had an implicit <code><a href="https://html.spec.whatwg.org/multipage/comms.html#messageport">MessagePort</a></code> associated with them. This port is part of a channel that is set up when the worker is created, but it is not exposed. This object must never be garbage collected before the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> object. All messages received by that port must immediately be retargeted at the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> object. That is, an event named <code>message</code> using the <code><a href="https://html.spec.whatwg.org/multipage/comms.html#messageevent">MessageEvent</a></code> interface is dispatched on <a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a> object. The <code><a href="https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-source">event.source</a></code> of these <code><a href="https://html.spec.whatwg.org/multipage/comms.html#messageevent">MessageEvent</a></code>s are instances of <code><a href="#service-worker-client-interface">ServiceWorkerClient</a></code>.</p>
    </section>
  </section>
  <section id="service-worker-client"><header><span class="section-number">4.2</span> <h1 data-bookmark-label="4.2 ServiceWorkerClient"><code>ServiceWorkerClient</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-client">¶</a></span></header>


<pre><code>[Constructor(<a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <var>url</var>), Exposed=ServiceWorker]
interface <dfn id="service-worker-client-interface" title="ServiceWorkerClient">ServiceWorkerClient</dfn> {
  readonly attribute <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a> ready;
  readonly attribute boolean hidden;
  readonly attribute boolean focused;
  readonly attribute <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> url;
  readonly attribute <a href="https://fetch.spec.whatwg.org/#concept-request-context-frame-type">ContextFrameType</a> frameType;
  void <a href="https://html.spec.whatwg.org/multipage/comms.html#dom-window-postmessage">postMessage</a>(any <var>message</var>, optional sequence&lt;<a href="https://html.spec.whatwg.org/multipage/infrastructure.html#transferable">Transferable</a>&gt; <var>transfer</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a> focus();
};
</code></pre>
    <p id="service-worker-client.1">The <code><a href="#service-worker-client-interface">ServiceWorkerClient</a></code> object has an associated <dfn id="dfn-service-worker-client-client">service worker client</dfn> (a <a href="#dfn-service-worker-client">service worker client</a>).</p>

    <p class="fixme" id="service-worker-client.2">This section will be updated as per <a href="https://github.com/slightlyoff/ServiceWorker/issues/414">SW #414</a>, <a href="https://github.com/slightlyoff/ServiceWorker/issues/423">SW #423</a>.</p>
  </section>
  <section id="service-worker-clients"><header><span class="section-number">4.3</span> <h1 data-bookmark-label="4.3 ServiceWorkerClients"><code>ServiceWorkerClients</code></h1><span class="anchor"><a style="text-decoration: none;" href="#service-worker-clients">¶</a></span></header>


<pre><code>[Exposed=ServiceWorker]
interface <dfn id="service-worker-clients-interface" title="ServiceWorkerClients">ServiceWorkerClients</dfn> {
  // The objects returned will be new instances every time
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;sequence&lt;<a href="#service-worker-client-interface">ServiceWorkerClient</a>&gt;?&gt; <a href="#service-worker-clients-getall-method">getAll</a>(optional <a href="#serviceworker-client-query-options-dictionary">ServiceWorkerClientQueryOptions</a> <var>options</var>);
};

dictionary <dfn id="serviceworker-client-query-options-dictionary" title="ServiceWorkerClientQueryOptions">ServiceWorkerClientQueryOptions</dfn> {
  boolean includeUncontrolled = false;
};
</code></pre>
    <p id="service-worker-clients.1">The <code><a href="#service-worker-clients-interface">ServiceWorkerClients</a></code> interface represents a container for a list of <code><a href="#service-worker-client-interface">ServiceWorkerClient</a></code> objects.</p>
    <section id="get-all-method"><header><span class="section-number">4.3.1</span> <h1 data-bookmark-label="4.3.1 getAll(options)"><code>getAll(<var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#get-all-method">¶</a></span></header>

      <p id="get-all-method.1">The <dfn id="service-worker-clients-getall-method"><code>getAll(<var>options</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
      <div class="algorithm">
      <ol>
        <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
        <li>Run these steps in parallel:
          <ol>
            <li>Let <var>clients</var> be an empty array.</li>
            <li>If the optional argument <var>options</var> is present and <var>options</var>.<var>includeUncontrolled</var> is true, then:
              <ol>
                <li>For each <a href="#dfn-service-worker-client">service worker client</a> <var>client</var> whose <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> is the <a href="https://html.spec.whatwg.org/multipage/browsers.html#same-origin">same</a> as the associated <a href="#dfn-service-worker">service worker</a>'s <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>:
                  <ol>
                    <li>Add a <code><a href="#service-worker-client-interface">ServiceWorkerClient</a></code> object that represent <var>client</var> to <var>clients</var>.</li>
                  </ol>
                  </li><li>Resolve <var>promise</var> with <var>clients</var>.</li>

              </ol>
            </li>
            <li>Else:
              <ol>
                <li>For each <a href="#dfn-service-worker-client">service worker client</a> <var>client</var> which are <a href="#dfn-control">controlled</a> by the associated <a href="#dfn-service-worker">service worker</a>:
                  <ol>
                    <li>Add a <code><a href="#service-worker-client-interface">ServiceWorkerClient</a></code> object that represent <var>client</var> to <var>clients</var>.</li>
                  </ol>
                </li>
                <li>Resolve <var>promise</var> with <var>clients</var>.</li>
              </ol>
            </li>
          </ol>
        </li>
        <li>Return <var>promise</var>.</li>
      </ol>
      </div>
      <p class="fixme" id="get-all-method.2">This section will be updated as per <a href="https://github.com/slightlyoff/ServiceWorker/issues/414">SW #414</a>.</p>
    </section>
  </section>

  <section id="cache-objects"><header><span class="section-number">4.4</span> <h1 data-bookmark-label="4.4 Caches">Caches</h1><span class="anchor"><a style="text-decoration: none;" href="#cache-objects">¶</a></span></header>


    <p id="cache-objects.1">To allow authors to fully manage their content caches for offline use, the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> execution context provides the caching methods largely conforming to <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-objects">ECMAScript 6 Map objects</a> with additional convenience methods. A domain can have multiple, named <code><a href="#cache-interface">Cache</a></code> objects, whose contents are entirely under the control of scripts. Caches are not shared across domains, and they are completely isolated from the browser's HTTP cache.</p>

    <section id="cache-lifetimes"><header><span class="section-number">4.4.1</span> <h1 data-bookmark-label="4.4.1 Understanding Cache Lifetimes">Understanding Cache Lifetimes</h1><span class="anchor"><a style="text-decoration: none;" href="#cache-lifetimes">¶</a></span></header>


      <p id="cache-lifetimes.1">The <code><a href="#cache-interface">Cache</a></code> instances are not part of the browser's HTTP cache. The <code><a href="#cache-interface">Cache</a></code> objects are exactly what authors have to manage themselves. The <code><a href="#cache-interface">Cache</a></code> objects do not get updated unless authors explicitly request them to be. The <code><a href="#cache-interface">Cache</a></code> objects do not expire unless authors delete the entries. The <code><a href="#cache-interface">Cache</a></code> objects do not disappear just because the <a href="#dfn-service-worker">service worker</a> script is updated. That is, caches are not updated automatically. Updates must be manually managed. This implies that authors should version their caches by name and make sure to use the caches only from the version of the ServiceWorker that can safely operate on.</p>
    </section>

    <section id="cache"><header><span class="section-number">4.4.2</span> <h1 data-bookmark-label="4.4.2 Cache"><code>Cache</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache">¶</a></span></header>

<pre><code>
[Exposed=ServiceWorker]
interface <dfn id="cache-interface" title="Cache">Cache</dfn> {
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="https://fetch.spec.whatwg.org/#response">Response</a>&gt; match(<a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>, optional <a href="#cache-query-options-dictionary">CacheQueryOptions</a> <var>options</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;sequence&lt;<a href="https://fetch.spec.whatwg.org/#response">Response</a>&gt;&gt; matchAll(optional <a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>, optional <a href="#cache-query-options-dictionary">CacheQueryOptions</a> <var>options</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;void&gt; add(<a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;void&gt; addAll(sequence&lt;<a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a>&gt; <var>requests</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;void&gt; put(<a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>, <a href="https://fetch.spec.whatwg.org/#response">Response</a> <var>response</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;boolean&gt; delete(<a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>, optional <a href="#cache-query-options-dictionary">CacheQueryOptions</a> <var>options</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;sequence&lt;<a href="https://fetch.spec.whatwg.org/#request">Request</a>&gt;&gt; keys(optional <a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>, optional <a href="#cache-query-options-dictionary">CacheQueryOptions</a> <var>options</var>);
};

dictionary <dfn id="cache-query-options-dictionary" title="CacheQueryOptions">CacheQueryOptions</dfn> {
  boolean ignoreSearch = false;
  boolean ignoreMethod = false;
  boolean ignoreVary = false;
  boolean prefixMatch = false;
  DOMString cacheName;
};

dictionary <dfn id="cache-batch-operation-dictionary" title="CacheBatchOperation">CacheBatchOperation</dfn> {
  DOMString type;
  Request request;
  Response response;
  CacheQueryOptions options;
};
</code></pre>
      <p id="cache.1">The <code><a href="#cache-interface">Cache</a></code> interface represents the storage for the pairs of a <a href="https://fetch.spec.whatwg.org/#request">Request</a> object and a <a href="https://fetch.spec.whatwg.org/#request">Response</a> object that are cached as part of the <a href="#dfn-service-worker">service worker</a> installation. A <code><a href="#cache-interface">Cache</a></code> object has a <a href="#request-to-response-map">[[RequestToResponseMap]]</a> object.</p>

      <p id="cache.2">Each <code><a href="#cache-interface">Cache</a></code> object is associated with a <a href="#request-to-response-map">[[RequestToResponseMap]]</a>. Multiple separate objects implementing the <code><a href="#cache-interface">Cache</a></code> interface across <a href="https://html.spec.whatwg.org/multipage/webappapis.html#worker-environment">service worker environments</a> can all be associated with the same <a href="#request-to-response-map">[[RequestToResponseMap]]</a> simultaneously.</p>

      <section id="cache-match"><header><span class="section-number">4.4.2.1</span> <h1 data-bookmark-label="4.4.2.1 match(request, options)"><code>match(<var>request</var>, <var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-match">¶</a></span></header>


        <p id="cache-match.1"><dfn id="cache-match-method"><code>match(<var>request</var>, <var>options</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
          <li>Run these steps in parallel:
            <ol>
              <li>Let <var>p</var> be the result of running the algorithm specified in <code><a href="#cache-matchall-method">matchAll(<var>request</var>, <var>options</var>)</a></code> method with <var>request</var> and <var>options</var> as the arguments.</li>
              <li>Wait until <var>p</var> settles.</li>
              <li>If <var>p</var> rejects with an exception, then:
                <ol>
                  <li>Reject <var>promise</var> with that exception.</li>
                </ol>
              </li>
              <li>Else if <var>p</var> resolves with an array, <var>responseArray</var>, then:
                <ol>
                  <li>If <var>responseArray</var> is an empty array, then:
                    <ol>
                      <li>Resolve <var>promise</var> with undefined.</li>
                    </ol>
                  </li>
                  <li>Else:
                    <ol>
                      <li>Resolve <var>promise</var> with the first element of <var>responseArray</var>.</li>
                    </ol>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Return <var>promise</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-matchall"><header><span class="section-number">4.4.2.2</span> <h1 data-bookmark-label="4.4.2.2 matchAll(request, options)"><code>matchAll(<var>request</var>, <var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-matchall">¶</a></span></header>


        <p id="cache-matchall.1"><dfn id="cache-matchall-method"><code>matchAll(<var>request</var>, <var>options</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
          <li>Run these steps in parallel:
            <ol>
              <li>Let <var>responseArray</var> be an empty array.</li>
              <li>If the optional argument <var>request</var> is omitted, then:
                <ol>
                  <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#request-to-response-map">[[RequestToResponseMap]]</a>, in key insertion order:
                    <ol>
                      <li>Add <var>entry</var>.[[value]] to <var>responseArray</var>.</li>
                    </ol>
                  </li>
                  <li>Resolve <var>promise</var> with <var>responseArray</var>.</li>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Else:
                <ol>
                  <li>Let <var>r</var> be null.</li>
                  <li>If <var>request</var> is a <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a>, then:
                    <ol>
                      <li>Set <var>r</var> to the associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a> of the result of invoking the initial value of <a href="https://fetch.spec.whatwg.org/#dom-request">Request</a> as constructor with <var>request</var> as its argument. If this throws an exception, return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with that exception.</li>
                    </ol>
                  </li>
                  <li>Else:
                    <ol>
                      <li>Set <var>r</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>.</li>
                    </ol>
                  </li>
                  <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-fragment">fragment</a> to null.</li>
                  <li>Let <var>entries</var> be the result of running <a href="#query-cache-algorithm">Query Cache</a> algorithm passing a <a href="https://fetch.spec.whatwg.org/#request">Request</a> object that represents <var>r</var> and <var>options</var> as the arguments.</li>
                  <li>For each <var>entry</var> of <var>entries</var>:
                    <ol>
                      <li>Add <var>entry</var>[1] to <var>responseArray</var>.</li>
                    </ol>
                  </li>
                  <li>Resolve <var>promise</var> with <var>responseArray</var>.</li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Return <var>promise</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-add"><header><span class="section-number">4.4.2.3</span> <h1 data-bookmark-label="4.4.2.3 add(request)"><code>add(<var>request</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-add">¶</a></span></header>


        <p id="cache-add.1"><dfn id="cache-add-method"><code>add(<var>request</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>requests</var> be an array containing only <var>request</var>.</li>
          <li>Set <var>responseArrayPromise</var> to the result of running the algorithm specified in <code><a href="#cache-addAll-method">addAll(<var>requests</var>)</a></code> passing <var>requests</var> as the argument.</li>
          <li>Let <var>p</var> be <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming <var>responseArrayPromise</var> with <var>onFulfilled</var></a>.</li>
          <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with value <var>responseArray</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
            <ol>
              <li>Resolve <var>p</var> with undefined.</li>
            </ol>
          </li>
          <li>Return <var>p</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-addAll"><header><span class="section-number">4.4.2.4</span> <h1 data-bookmark-label="4.4.2.4 addAll(requests)"><code>addAll(<var>requests</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-addAll">¶</a></span></header>


        <p id="cache-addAll.1"><dfn id="cache-addAll-method"><code>addAll(<var>requests</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>responsePromiseArray</var> be an empty array.</li>
          <li>Let <var>requestArray</var> be an empty array.</li>
          <li>For each <var>request</var> in <var>requests</var>:
            <ol>
              <li>Let <var>r</var> be null.</li>
              <li>If <var>request</var> is a <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a>, then:
                <ol>
                  <li>Set <var>r</var> to the associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a> of the result of invoking the initial value of <a href="https://fetch.spec.whatwg.org/#dom-request">Request</a> as constructor with <var>request</var> as its argument. If this throws an exception, return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with that exception.</li>
                </ol>
              </li>
              <li>Else:
                <ol>
                  <li>Set <var>r</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>.</li>
                </ol>
              </li>
              <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-fragment">fragment</a> to null.</li>
              <li>Add a <a href="https://fetch.spec.whatwg.org/#request">Request</a> object that represents <var>r</var> to <var>requestArray</var>.</li>
              <li>If <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-scheme">scheme</a> is not one of "<code>http</code>" and "<code>https</code>", then:
                <ol>
                  <li>Add a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with a "<code><a href="http://heycam.github.io/webidl/#networkerror">NetworkError</a></code>" exception to <var>responsePromiseArray</var>.</li>
                  <li>Continue to the next iteration of the loop.</li>
                </ol>
              </li>
              <li>Run the algorithm specified in <code><a href="https://fetch.spec.whatwg.org/#dom-global-fetch">fetch(<var>input</var>, <var>init</var>)</a></code> with <var>r</var> and add the returned value to <var>responsePromiseArray</var>.</li>
            </ol>
          </li>
          <li>Let <var>p</var> be <a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/writing-specifications-with-promises.md#aggregating-promises">waiting for all of <var>responsePromiseArray</var></a>.</li>
          <li>Let <var>q</var> be <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming <var>p</var> with <var>onFulfilled</var>.</a></li>
          <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with value <var>responseArray</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
            <ol>
              <li>Let <var>operations</var> be an empty array.</li>
              <li>For each <var>response</var> in <var>responseArray</var> with the index <var>index</var>:
                <ol>
                  <li>Let <var>o</var> be an empty object representing a <code><a href="#cache-batch-operation-dictionary">CacheBatchOperation</a></code> dictionary.</li>
                  <li>Set the <var>type</var> dictionary member of <var>o</var> to "put".</li>
                  <li>Set the <var>request</var> dictionary member of <var>o</var> to <var>requestArray</var>[<var>index</var>].</li>
                  <li>Set the <var>response</var> dictionary member of <var>o</var> to <var>response</var>.</li>
                  <li>Add <var>o</var> to <var>operations</var>.</li>
                </ol>
              </li>
              <li>Let <var>resultPromise</var> to the result of running <a href="#batch-cache-operations-algorithm">Batch Cache Operations</a> algorithm passing <var>operations</var> as the argument.</li>
              <li>Resolve <var>q</var> with undefined.</li>
            </ol>
          </li>
          <li>Return <var>q</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-put"><header><span class="section-number">4.4.2.5</span> <h1 data-bookmark-label="4.4.2.5 put(request, response)"><code>put(<var>request</var>, <var>response</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-put">¶</a></span></header>


        <p id="cache-put.1"><dfn id="cache-put-method"><code>put(<var>request</var>, <var>response</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>r</var> be null.</li>
          <li>If <var>request</var> is a <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a>, then:
            <ol>
              <li>Set <var>r</var> to the associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a> of the result of invoking the initial value of <a href="https://fetch.spec.whatwg.org/#dom-request">Request</a> as constructor with <var>request</var> as its argument. If this throws an exception, return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with that exception.</li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Set <var>r</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>.</li>
            </ol>
          </li>
          <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-fragment">fragment</a> to null.</li>
          <li>Let <var>operations</var> be an empty array.</li>
          <li>Let <var>o</var> be an empty object representing a <code><a href="#cache-batch-operation-dictionary">CacheBatchOperation</a></code> dictionary.</li>
          <li>Set the <var>type</var> dictionary member of <var>o</var> to "put".</li>
          <li>Set the <var>request</var> dictionary member of <var>o</var> to a <a href="https://fetch.spec.whatwg.org/#request">Request</a> object that represents <var>r</var>.</li>
          <li>Set the <var>response</var> dictionary member of <var>o</var> to <var>response</var>.</li>
          <li>Add <var>o</var> to <var>operations</var>.</li>
          <li>Let <var>resultPromise</var> to the result of running <a href="#batch-cache-operations-algorithm">Batch Cache Operations</a> passing <var>operations</var> as the argument.</li>
          <li>Let <var>p</var> be <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming <var>resultPromise</var> with <var>onFulfilled</var></a>.</li>
          <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with <var>responseArray</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
            <ol>
              <li>Resolve <var>p</var> with undefined.</li>
            </ol>
          </li>
          <li>Return <var>p</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-delete"><header><span class="section-number">4.4.2.6</span> <h1 data-bookmark-label="4.4.2.6 delete(request, options)"><code>delete(<var>request</var>, <var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-delete">¶</a></span></header>


        <p id="cache-delete.1"><dfn id="cache-delete-method"><code>delete(<var>request</var>, <var>options</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>r</var> be null.</li>
          <li>If <var>request</var> is a <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a>, then:
            <ol>
              <li>Set <var>r</var> to the associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a> of the result of invoking the initial value of <a href="https://fetch.spec.whatwg.org/#dom-request">Request</a> as constructor with <var>request</var> as its argument. If this throws an exception, return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with that exception.</li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Set <var>r</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>.</li>
            </ol>
          </li>
          <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-fragment">fragment</a> to null.</li>
          <li>Let <var>operations</var> be an empty array.</li>
          <li>Let <var>o</var> be an empty object representing a <code><a href="#cache-batch-operation-dictionary">CacheBatchOperation</a></code> dictionary.</li>
          <li>Set the <var>type</var> dictionary member of <var>o</var> to "delete".</li>
          <li>Set the <var>request</var> dictionary member of <var>o</var> to a <a href="https://fetch.spec.whatwg.org/#request">Request</a> object that represents <var>r</var>.</li>
          <li>Set the <var>options</var> dictionary member of <var>o</var> to <var>options</var>.</li>
          <li>Add <var>o</var> to <var>operations</var>.</li>
          <li>Let <var>resultPromise</var> to the result of running <a href="#batch-cache-operations-algorithm">Batch Cache Operations</a> passing <var>operations</var> as the argument.</li>
          <li>Let <var>p</var> be <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming <var>resultPromise</var> with <var>onFulfilled</var></a>.</li>
          <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with <var>responseArray</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
            <ol>
              <li>If <var>responseArray</var> is not null, then:
                <ol>
                  <li>Resolve <var>p</var> with true.</li>
                </ol>
              </li>
              <li>Else:
                <ol>
                  <li>Resolve <var>p</var> with false.</li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Return <var>p</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-keys"><header><span class="section-number">4.4.2.7</span> <h1 data-bookmark-label="4.4.2.7 keys(request, options)"><code>keys(<var>request</var>, <var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-keys">¶</a></span></header>


        <p id="cache-keys.1"><dfn id="cache-keys-method"><code>keys(<var>request</var>, <var>options</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
          <li>Run these steps in parallel:
            <ol>
              <li>Let <var>resultArray</var> be an empty array.</li>
              <li>If the optional argument <var>request</var> is omitted, then:
                <ol>
                  <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#request-to-response-map">[[RequestToResponseMap]]</a>, in key insertion order:
                    <ol>
                      <li>Add <var>entry</var>.[[key]] to <var>resultArray</var>.</li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li>Else:
                <ol>
                  <li>Let <var>r</var> be null.</li>
                  <li>If <var>request</var> is a <a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a>, then:
                    <ol>
                      <li>Set <var>r</var> to the associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a> of the result of invoking the initial value of <a href="https://fetch.spec.whatwg.org/#dom-request">Request</a> as constructor with <var>request</var> as its argument. If this throws an exception, return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with that exception.</li>
                    </ol>
                  </li>
                  <li>Else:
                    <ol>
                      <li>Set <var>r</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>.</li>
                    </ol>
                  </li>
                  <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-fragment">fragment</a> to null.</li>
                  <li>Let <var>requestResponseArray</var> be the result of running <a href="#query-cache-algorithm">Query Cache</a> algorithm passing a <a href="https://fetch.spec.whatwg.org/#request">Request</a> object that represents <var>r</var> and <var>options</var> as the arguments.</li>
                  <li>For each <var>requestResponse</var> in <var>requestResponseArray</var>:
                    <ol>
                      <li>Add <var>requestResponse</var>[0] to <var>resultArray</var>.</li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li>Resolve <var>promise</var> with <var>resultArray</var>.</li>
            </ol>
          </li>
          <li>Return <var>promise</var>.</li>
        </ol>
        </div>
      </section>
    </section>

    <section id="cache-storage"><header><span class="section-number">4.4.3</span> <h1 data-bookmark-label="4.4.3 CacheStorage"><code>CacheStorage</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-storage">¶</a></span></header>


<pre><code>
[Exposed=ServiceWorker]
interface <dfn id="cache-storage-interface" title="CacheStorage">CacheStorage</dfn> {
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="https://fetch.spec.whatwg.org/#response">Response</a>&gt; match(<a href="https://fetch.spec.whatwg.org/#requestinfo">RequestInfo</a> <var>request</var>, optional <a href="#cache-query-options-dictionary">CacheQueryOptions</a> <var>options</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;boolean&gt; has(DOMString <var>cacheName</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="#cache-interface">Cache</a>&gt; open(DOMString <var>cacheName</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;boolean&gt; delete(DOMString <var>cacheName</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;sequence&lt;DOMString&gt;&gt; keys();
};</code></pre>

      <p class="note" id="cache-storage.1"><a href="#cache-storage-interface">CacheStorage</a> interface is designed to largely conform to <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-objects">ECMAScript 6 Map objects</a> but entirely async, and with additional convenience methods. The methods, <code>clear</code>, <code>forEach</code>, <code>entries</code> and <code>values</code>, are intentionally excluded from the scope of the first version resorting to the ongoing discussion about the async iteration by TC39.</p>

      <p id="cache-storage.2">The <code><a href="#cache-storage-interface">CacheStorage</a></code> interface represents the storage for <code><a href="#cache-interface">Cache</a></code> objects. A <code><a href="#cache-storage-interface">CacheStorage</a></code> object has a <a href="#name-to-cache-map">[[NameToCacheMap]]</a> object.</p>

      <section id="cache-storage-match"><header><span class="section-number">4.4.3.1</span> <h1 data-bookmark-label="4.4.3.1 match(request, options)"><code>match(<var>request</var>, <var>options</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-storage-match">¶</a></span></header>


        <p id="cache-storage-match.1"><dfn id="cache-storage-match-method"><code>match(<var>request</var>, <var>options</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>cacheName</var> be null.</li>
          <li>If the optional argument <var>options</var> is not omitted, then:
            <ol>
              <li>Set <var>cacheName</var> to <var>options</var>.<var>cacheName</var>.</li>
            </ol>
          </li>
          <li>If <var>cacheName</var> is not null, then:
            <ol>
              <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>, <var>p</var>, resolved with the result of running the following substeps:
                <ol>
                  <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#name-to-cache-map">[[NameToCacheMap]]</a>, in key insertion order:
                    <ol>
                      <li>If <var>cacheName</var> matches <var>entry</var>.[[key]], then:
                        <ol>
                          <li>Resolve <var>p</var> with the result of running the algorithm specified in <code><a href="#cache-match-method">match(<var>request</var>, <var>options</var>)</a></code> method of <code><a href="#cache-interface">Cache</a></code> interface with <var>request</var> and <var>options</var> as the arguments (providing <var>entry</var>.[[value]] as thisArgument to the <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist">[[Call]]</a> internal method of <code><a href="#cache-match-method">match(<var>request</var>, <var>options</var>)</a></code>.)</li>
                          <li>Abort these steps.</li>
                        </ol>
                      </li>
                    </ol>
                  </li>
                  <li>Reject <var>p</var> with an "<code><a href="http://heycam.github.io/webidl/#notfounderror">NotFoundError</a></code>" exception.</li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Set <var>p</var> to <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming</a> the result of running the algorithm specified in <code><a href="#cache-storage-keys-method">keys()</a></code> method, with <var>onFulfilled</var>.</li>
              <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with value <var>keys</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
                <ol>
                  <li>For each <var>key</var> in <var>keys</var>:
                    <ol>
                      <li>Let <var>q</var> be the result of running the algorithm specified in <code><a href="#cache-match-method">match(<var>request</var>, <var>options</var>)</a></code> method of <code><a href="#cache-interface">Cache</a></code> interface with <var>request</var> and <var>options</var> as the arguments (providing <var>key</var> as thisArgument to the <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist">[[Call]]</a> internal method of <code><a href="#cache-match-method">match(<var>request</var>, <var>options</var>)</a></code>.)</li>
                      <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>q</var> with value <var>matchedResponse</var></a>:
                        <ol>
                          <li>If <var>matchedResponse</var> is not undefined, then:
                            <ol>
                              <li>Resolve <var>p</var> with <var>matchedResponse</var>.</li>
                              <li>Abort these steps.</li>
                            </ol>
                          </li>
                        </ol>
                      </li>
                      <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-rejection">Upon rejection of <var>q</var> with value <var>err</var></a>:
                        <ol>
                          <li>Reject <var>p</var> with <var>err</var>.</li>
                          <li>Abort these steps.</li>
                        </ol>
                      </li>
                    </ol>
                  </li>
                  <li>Resolve <var>p</var> with undefined.</li>
                </ol>
              </li>
              <li>Return <var>p</var>.</li>
            </ol>
          </li>
        </ol>
        </div>
      </section>

      <section id="cache-storage-has"><header><span class="section-number">4.4.3.2</span> <h1 data-bookmark-label="4.4.3.2 has(cacheName)"><code>has(<var>cacheName</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-storage-has">¶</a></span></header>


        <p id="cache-storage-has.1"><dfn id="cache-storage-has-method"><code>has(<var>cacheName</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>, <var>p</var>, resolved with the result of running the following substeps:
            <ol>
              <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#name-to-cache-map">[[NameToCacheMap]]</a>, in key insertion order:
                <ol>
                  <li>If <var>cacheName</var> matches <var>entry</var>.[[key]], then:
                    <ol>
                      <li>Return true.</li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li>Return false.</li>
            </ol>
          </li>
        </ol>
        </div>
      </section>

      <section id="cache-storage-open"><header><span class="section-number">4.4.3.3</span> <h1 data-bookmark-label="4.4.3.3 open(cacheName)"><code>open(<var>cacheName</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-storage-open">¶</a></span></header>


        <p id="cache-storage-open.1"><dfn id="cache-storage-open-method"><code>open(<var>cacheName</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>, <var>p</var>, resolved with the result of running the following substeps:
            <ol>
              <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#name-to-cache-map">[[NameToCacheMap]]</a>, in key insertion order:
                <ol>
                  <li>If <var>cacheName</var> matches <var>entry</var>.[[key]], then:
                    <ol>
                      <li>Return a new <code><a href="#cache-interface">Cache</a></code> object which is a copy of <var>entry</var>.[[value]].</li>
                      <li>Abort these steps.</li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li>Let <var>cache</var> be a new <code><a href="#cache-interface">Cache</a></code> object.</li>
              <li>Set a newly-created Record {[[key]]: <var>cacheName</var>, [[value]]: <var>cache</var>} to <a href="#name-to-cache-map">[[NameToCacheMap]]</a>.</li>
              <li>Return <var>cache</var>.</li>
            </ol>
          </li>
        </ol>
        </div>
      </section>

      <section id="cache-storage-delete"><header><span class="section-number">4.4.3.4</span> <h1 data-bookmark-label="4.4.3.4 delete(cacheName)"><code>delete(<var>cacheName</var>)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-storage-delete">¶</a></span></header>


        <p id="cache-storage-delete.1"><dfn id="cache-storage-cacheName-method"><code>delete(<var>cacheName</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>p</var> be the result of running the algorithm specified in <code><a href="#cache-storage-has-method">has(<var>cacheName</var>)</a></code> method with <var>cacheName</var> as the argument.</li>
          <li>Let <var>q</var> be <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming <var>p</var> with <var>onFulfilled</var></a>.</li>
          <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with value <var>cacheExists</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
            <ol>
              <li>If <var>cacheExists</var> is true, then:
                <ol>
                  <li>Delete a Record {[[key]], [[value]]} <var>entry</var> of its <a href="#name-to-cache-map">[[NameToCacheMap]]</a> where <var>cacheName</var> matches entry.[[key]].</li>
                  <li>Resolve <var>q</var> with true.</li>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Else:
                <ol>
                  <li>Resolve <var>q</var> with flase.</li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Return <var>q</var>.</li>
        </ol>
        </div>
      </section>

      <section id="cache-storage-keys"><header><span class="section-number">4.4.3.5</span> <h1 data-bookmark-label="4.4.3.5 keys()"><code>keys()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#cache-storage-keys">¶</a></span></header>


        <p id="cache-storage-keys.1"><dfn id="cache-storage-keys-method"><code>keys()</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>

        <p class="note" id="cache-storage-keys.2">The promise returned from this method resolves with the sequence of keys, cache names in DOMString, in insertion order.</p>

        <div class="algorithm">
        <ol>
          <li>Let <var>resultArray</var> be an empty array.</li>
          <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>, <var>p</var>, resolved with the result of running the following substeps:
            <ol>
              <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#name-to-cache-map">[[NameToCacheMap]]</a>, in key insertion order:
                <ol>
                  <li>Add <var>entry</var>.[[key]] to <var>resultArray</var>.</li>
                </ol>
              </li>
              <li>Return <var>resultArray</var>.</li>
            </ol>
          </li>
        </ol>
        </div>
      </section>
    </section>
  </section>

  <section id="extendable-event"><header><span class="section-number">4.5</span> <h1 data-bookmark-label="4.5 ExtendableEvent"><code>ExtendableEvent</code></h1><span class="anchor"><a style="text-decoration: none;" href="#extendable-event">¶</a></span></header>


<pre><code>
[Constructor(DOMString <var>type</var>, optional <a href="#extendable-event-init-dictionary">ExtendableEventInit</a> <var>eventInitDict</var>), Exposed=ServiceWorker]
interface <dfn id="extendable-event-interface" title="ExtendableEvent">ExtendableEvent</dfn> : <a href="https://dom.spec.whatwg.org/#event">Event</a> {
  void <a href="#extendable-event-waituntil-method">waitUntil</a>(<a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;any&gt; <var>f</var>);
};

dictionary <dfn id="extendable-event-init-dictionary" title="ExtendableEventInit">ExtendableEventInit</dfn> : <a href="https://dom.spec.whatwg.org/#eventinit">EventInit</a> {
  // Defined for the forward compatibility across the derived events
};
</code></pre>

    <p id="extendable-event.1"><a href="#dfn-service-worker">Service workers</a> have two <a href="#dfn-lifecycle-events">lifecycle events</a>, <code><a href="#service-worker-global-scope-install-event">install</a></code> and <code><a href="#service-worker-global-scope-activate-event">activate</a></code>. <a href="#dfn-service-worker">Service workers</a> use the <code><a href="#extendable-event-interface">ExtendableEvent</a></code> interface for <code><a href="#service-worker-global-scope-activate-event">activate</a></code> event and the <code><a href="#install-event-interface">InstallEvent</a></code> interface, which inherits from the <code><a href="#extendable-event-interface">ExtendableEvent</a></code> interface, for <code><a href="#service-worker-global-scope-install-event">install</a></code> event. <a href="#extensibility">Service worker extensions</a> that <a href="#extension-to-service-worker-global-scope">define event handlers</a> may also use the <code><a href="#extendable-event-interface">ExtendableEvent</a></code> interface.</p>

    <p id="extendable-event.2">Each event using <code><a href="#extendable-event-interface">ExtendableEvent</a></code> interface or a derived interface has the following associated flags that are all initially unset:
      </p><ul>
        <li><dfn id="extend-lifetime-flag">extend lifetime flag</dfn></li>
        <li><dfn id="wait-until-reject-flag">wait-until reject flag</dfn></li>
      </ul>
    <p id="extendable-event.3"></p>

    <section id="wait-until-method"><header><span class="section-number">4.5.1</span> <h1 data-bookmark-label="4.5.1 event.waitUntil(f)"><code>event.waitUntil(f)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#wait-until-method">¶</a></span></header>


      <p id="wait-until-method.1"><a href="#extendable-event-waituntil-method"><code>waitUntil(<var>f</var>)</code></a> method, extends the lifetime of the event. When called in <code><a href="#service-worker-global-scope-oninstall-attribute">oninstall</a></code>, it delays treating the <a href="#dfn-installing-worker">installing worker</a> as <em><a href="#dfn-state">installed</a></em> (i.e. a <a href="#dfn-waiting-worker">waiting worker</a>) until the passed <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolves successfully. This is primarily used to ensure that a <a href="#dfn-service-worker">service worker</a> is not considered <em><a href="#dfn-state">installed</a></em> (i.e. a <a href="#dfn-waiting-worker">waiting worker</a>) until all of the core caches it depends on are populated. When called in <code><a href="#service-worker-global-scope-onactivate-attribute">onactivate</a></code>, it delays treating the <a href="#dfn-active-worker">active worker</a> as <em><a href="#dfn-state">activated</a></em> until the passed <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolves successfully. This is primarily used to ensure that any <a href="#dfn-functional-events">functional events</a> are not dispatched to the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> object that represents the <a href="#dfn-service-worker">service worker</a> until it upgrades database schemas and deletes the outdated cache entries. <a href="#extensibility">Service worker extensions</a> that <a href="#extension-to-service-worker-global-scope">define event handlers</a> will define their own behaviours, allowing the <a href="#extend-lifetime-flag">extend lifetime flag</a> to suggest operation length, and the <a href="#wait-until-reject-flag">wait-until reject flag</a> to suggest operation failure.</p>

      <p id="wait-until-method.2"><dfn id="extendable-event-waituntil-method"><code>waitUntil(<var>f</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
      <div class="algorithm">
      <ol>
        <li>Set the <a href="#extend-lifetime-flag">extend lifetime flag</a>.</li>
        <li>Run the following substeps in parallel:
          <ol>
            <li>Wait until <var>f</var> settles.</li>
            <li>If <var>f</var> rejected, then:
              <ol>
                <li>Set the <a href="#wait-until-reject-flag">wait-until reject flag</a>.</li>
              </ol>
            </li>
            <li>Else if <var>f</var> resolved with a value, then:
              <ol>
                <li>Do nothing.</li>
              </ol>
            </li>
            <li>Unset the <a href="#extend-lifetime-flag">extend lifetime flag</a>.</li>
          </ol>
        </li>
      </ol>
      </div>
    </section>
  </section>

  <section id="install-event-section"><header><span class="section-number">4.6</span> <h1 data-bookmark-label="4.6 InstallEvent"><code>InstallEvent</code></h1><span class="anchor"><a style="text-decoration: none;" href="#install-event-section">¶</a></span></header>


<pre><code>
[Constructor(DOMString <var>type</var>, optional <a href="#install-event-init-dictionary">InstallEventInit</a> <var>eventInitDict</var>), Exposed=ServiceWorker]
interface <dfn id="install-event-interface" title="InstallEvent">InstallEvent</dfn> : <a href="#extendable-event-interface">ExtendableEvent</a> {
  readonly attribute <a href="#service-worker-interface">ServiceWorker</a>? activeWorker;
};

dictionary <dfn id="install-event-init-dictionary" title="InstallEventInit">InstallEventInit</dfn> : <a href="https://dom.spec.whatwg.org/#eventinit">EventInit</a> {
  <a href="#service-worker-interface">ServiceWorker</a> activeWorker;
};
</code></pre>
  </section>

  <section id="fetch-event-section"><header><span class="section-number">4.7</span> <h1 data-bookmark-label="4.7 FetchEvent"><code>FetchEvent</code></h1><span class="anchor"><a style="text-decoration: none;" href="#fetch-event-section">¶</a></span></header>


<pre><code>
[Constructor(DOMString <var>type</var>, optional <a href="#fetch-event-init-dictionary">FetchEventInit</a> <var>eventInitDict</var>), Exposed=ServiceWorker]
interface <dfn id="fetch-event-interface" title="FetchEvent">FetchEvent</dfn> : <a href="https://dom.spec.whatwg.org/#event">Event</a> {
  readonly attribute <a href="https://fetch.spec.whatwg.org/#request">Request</a> request;
  readonly attribute <a href="#service-worker-client-interface">ServiceWorkerClient</a> client;
  readonly attribute boolean <a href="#fetch-event-isreload-attribute">isReload</a>;

  void <a href="#fetch-event-respondwith-method">respondWith</a>((<a href="https://fetch.spec.whatwg.org/#response">Response</a> or <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="https://fetch.spec.whatwg.org/#response">Response</a>&gt;) <var>r</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="https://fetch.spec.whatwg.org/#response">Response</a>&gt; forwardTo(<a href="http://heycam.github.io/webidl/#idl-USVString">USVString</a> <var>url</var>);
  <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">Promise</a>&lt;<a href="https://fetch.spec.whatwg.org/#response">Response</a>&gt; <a href="#fetch-event-default-method">default</a>();
};

dictionary <dfn id="fetch-event-init-dictionary" title="FetchEventInit">FetchEventInit</dfn> : <a href="https://dom.spec.whatwg.org/#eventinit">EventInit</a> {
  <a href="https://fetch.spec.whatwg.org/#request">Request</a> request;
  <a href="#service-worker-client-interface">ServiceWorkerClient</a> client;
  boolean isReload;
};
</code></pre>

    <p id="fetch-event-section.1">Each event using <code><a href="#fetch-event-interface">FetchEvent</a></code> interface has the following associated flag that is initially unset:
      </p><ul>
        <li><dfn id="wait-to-respond-flag">wait to respond flag</dfn></li>
        <li><dfn id="respond-with-entered-flag">respond-with entered flag</dfn></li>
        <li><dfn id="respond-with-error-flag">respond-with error flag</dfn></li>
      </ul>
    <p id="fetch-event-section.2"></p>

    <section id="respond-with-method"><header><span class="section-number">4.7.1</span> <h1 data-bookmark-label="4.7.1 event.respondWith(r)"><code>event.respondWith(r)</code></h1><span class="anchor"><a style="text-decoration: none;" href="#respond-with-method">¶</a></span></header>


      <p id="respond-with-method.1">When <code><a href="#fetch-event-respondwith-method">event.respondWith(<var>r</var>)</a></code> method is invoked, the argument, <var>r</var>, must resolve with a <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>, else a <a href="https://fetch.spec.whatwg.org/#concept-network-error">network error</a> is returned to <a href="https://fetch.spec.whatwg.org/#concept-fetch">Fetch</a>. If the request is a top-level navigation and the return value is a <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> whose <code>type</code> attribute is "<code>opaque</code>" (i.e., an opaque response body), a <a href="https://fetch.spec.whatwg.org/#concept-network-error">network error</a> is returned to <a href="https://fetch.spec.whatwg.org/#concept-fetch">Fetch</a>. The final URL of all successful (non network-error) responses is the <a href="https://fetch.spec.whatwg.org/#concept-request-url">requested</a> URL. Renderer-side security checks about tainting for cross-origin content are tied to the transparency (or opacity) of the <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> body, not URLs.</p>

      <p id="respond-with-method.2"><dfn id="fetch-event-respondwith-method"><code>respondWith(<var>r</var>)</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
      <div class="algorithm">
      <ol>
        <li>If the <a href="#respond-with-entered-flag">respond-with entered flag</a> is set, then:
          <ol>
            <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> an "<code><a href="http://heycam.github.io/webidl/#invalidstateerror">InvalidStateError</a></code>" exception.</li>
            <li>Abort these steps.</li>
          </ol>
        </li>
        <li>Set the <a href="#respond-with-entered-flag">respond-with entered flag</a>.</li>
        <li>Set the <a href="#wait-to-respond-flag">wait to respond flag</a>.</li>
        <li>Run the following substeps in parallel:
          <ol>
            <li>Wait until <var>r</var> settles.</li>
            <li>If <var>r</var> rejected, then:
              <ol>
                <li>Set the <a href="#respond-with-error-flag">respond-with error flag</a>.</li>
              </ol>
            </li>
            <li>If <var>r</var> resolved with <var>response</var>, then:
              <ol>
                <li>If <var>response</var> is an instance of <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> interface, then:
                  <ol>
                    <li>Let <var>request</var> be the value that the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <code>request</code> attribute's getter returns</li>
                    <li>If <var>response</var>.<var>type</var> is "<code>opaque</code>", and <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>'s <code><a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a></code> is one of <em>frame</em>, <em>hyperlink</em>, <em>iframe</em>, <em>location</em>, and <em>sharedworker</em>, then:
                      <ol>
                        <li>Set the <a href="#respond-with-error-flag">respond-with error flag.</a>
                      </li></ol>
                    </li>
                  </ol>
                </li>
                <li>Else:
                  <ol>
                    <li>Set the <a href="#respond-with-error-flag">respond-with error flag.</a>
                  </li></ol>
                  <p class="note">If the <a href="#respond-with-error-flag">respond-with error flag</a> is set, a <a href="https://fetch.spec.whatwg.org/#concept-network-error">network error</a> is returned to <a href="https://fetch.spec.whatwg.org/#concept-fetch">Fetch</a> through <a href="#on-fetch-request-algorithm">Handle Fetch</a> algorithm. (See the step 25.1.) Otherwise, the value <var>response</var> is returned to <a href="https://fetch.spec.whatwg.org/#concept-fetch">Fetch</a> through <a href="#on-fetch-request-algorithm">Handle Fetch</a> algorithm. (See the step 26.1.)</p>
                </li>
              </ol>
            </li>
            <li>Unset the <a href="#wait-to-respond-flag">wait to respond flag</a>.</li>
          </ol>
        </li>
      </ol>
      </div>
    </section>

    <section id="default-method"><header><span class="section-number">4.7.2</span> <h1 data-bookmark-label="4.7.2 event.default()"><code>event.default()</code></h1><span class="anchor"><a style="text-decoration: none;" href="#default-method">¶</a></span></header>


      <p id="default-method.1">The invocation of <code><a href="#fetch-event-default-method">event.default()</a></code> method performs a <a href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</a> using <code>event.request</code>. <code>event.request</code> represents the original request from the <a href="#dfn-control">controlled</a> <a href="#dfn-service-worker-client">service worker client</a>. During the execution, the original request is not altered (except the <a href="https://fetch.spec.whatwg.org/#skip-service-worker-flag">skip service worker flag</a>), and thus <code><a href="#fetch-event-default-method">event.default()</a></code> fetches the original request through the UA's HTTP stack. <code><a href="#fetch-event-default-method">event.default()</a></code> returns a promise, which resolves with a <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> object, that can be an argument to the <code><a href="#fetch-event-respondwith-method">event.respondWith(<var>r</var>)</a></code> method.</p>

      <p id="default-method.2"><dfn id="fetch-event-default-method"><code>default()</code></dfn> method must run these steps or their <a href="#dfn-processing-equivalence">equivalent</a>:</p>
      <div class="algorithm">
      <ol>
        <li>If <a href="https://dom.spec.whatwg.org/#concept-event">event</a>'s <a href="https://dom.spec.whatwg.org/#dispatch-flag">dispatch flag</a> is unset, then:
          <ol>
            <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with a "<code><a href="http://heycam.github.io/webidl/#invalidstateerror">InvalidStateError</a></code>" exception.</li>
          </ol>
        </li>
        <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
        <li>Run the following substeps in parallel:
          <ol>
            <li>Let <var>r</var> be the value that the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <code>request</code> attribute's getter returns.</li>
            <li>Let <var>request</var> be <var>r</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a>.</li>
            <li>Set <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#skip-service-worker-flag">skip service worker flag</a> and <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#synchronous-flag">synchronous flag</a>.</li>
            <li>Let <var>response</var> be the result of running <a href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</a> with <var>request</var> as its argument.</li>
            <li>If <var>response</var> is a <a href="https://fetch.spec.whatwg.org/#concept-network-error">network error</a>, then:
              <ol>
                <li>Reject <var>promise</var> with a <code>TypeError</code>.</li>
              </ol>
            </li>
            <li>Else:
              <ol>
                <li>Resolve <var>promise</var> with a new <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> object associated with <var>response</var>.</li>
              </ol>
            </li>
          </ol>
        </li>
        <li>Return <var>promise.</var></li>
      </ol>
      </div>
    </section>

    <section id="is-reload-attribute"><header><span class="section-number">4.7.3</span> <h1 data-bookmark-label="4.7.3 event.isReload"><code>event.isReload</code></h1><span class="anchor"><a style="text-decoration: none;" href="#is-reload-attribute">¶</a></span></header>


      <p id="is-reload-attribute.1"><dfn id="fetch-event-isreload-attribute"><code>isReload</code></dfn> attribute must return true if <var>event</var> was dispatched with the user's intention for the page reload, and false otherwise. Pressing the refresh button should be considered a reload while clicking a link and pressing the back button should not. The behavior of the <var>Ctrl+l enter</var> is left to the implementations of the user agents.</p>
    </section>
  </section>

  <section id="execution-context-events"><header><span class="section-number">4.8</span> <h1 data-bookmark-label="4.8 Events">Events</h1><span class="anchor"><a style="text-decoration: none;" href="#execution-context-events">¶</a></span></header>


    <p id="execution-context-events.1">The following events are dispatched on <a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a> object:</p>

    <table>
      <thead>
        <tr>
          <th>Event name</th>
          <th>Interface</th>
          <th>Dispatched when…</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><dfn id="service-worker-global-scope-install-event"><code>install</code></dfn></td>
          <td><code><a href="#install-event-interface">InstallEvent</a></code></td>
          <td>[<a href="#dfn-lifecycle-events">Lifecycle event</a>] A <a href="#dfn-service-worker-registration">service worker registration</a> acquires a new <a href="#dfn-installing-worker">installing worker</a>. (See step 4.7.3 of the <a href="#installation-algorithm">Install</a> algorithm.)</td>
        </tr>
        <tr>
          <td><dfn id="service-worker-global-scope-activate-event"><code>activate</code></dfn></td>
          <td><code><a href="#extendable-event-interface">ExtendableEvent</a></code></td>
          <td>[<a href="#dfn-lifecycle-events">Lifecycle event</a>] A <a href="#dfn-service-worker-registration">service worker registration</a> acquires a new <a href="#dfn-active-worker">active worker</a>. (See step 1.10.3 of the <a href="#activation-algorithm">Activate</a> algorithm.)</td>
        </tr>
        <tr>
          <td><dfn id="service-worker-global-scope-fetch-event"><code>fetch</code></dfn></td>
          <td><code><a href="#fetch-event-interface">FetchEvent</a></code></td>
          <td>[<a href="#dfn-functional-events">Functional event</a>] <a href="https://fetch.spec.whatwg.org/">Fetch</a> invokes <a href="#on-fetch-request-algorithm">Handle Fetch</a> with <var>request</var>. As a result of performing <a href="#on-fetch-request-algorithm">Handle Fetch</a>, the Service Woker returns a <a href="https://fetch.spec.whatwg.org/#concept-response">response</a> to <a href="https://fetch.spec.whatwg.org/">Fetch</a>. The <a href="https://fetch.spec.whatwg.org/#concept-response">response</a>, represented by a <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> object, can be retrieved from a <a href="#cache-interface">Cache</a> object or directly from network using <code><a href="https://fetch.spec.whatwg.org/#dom-global-fetch">self.fetch(<var>input</var>, <var>init</var>)</a></code> method or <code><a href="#fetch-event-default-method">event.default()</a></code> method. (A custom <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> object can be another option.)</td>
        </tr>
      </tbody>
    </table>

    <p class="note" id="execution-context-events.2">Custom event types for <dfn id="service-worker-global-scope-beforeevicted-event">beforeevicted</dfn> and <dfn id="service-worker-global-scope-evicted-event">evicted</dfn> should be added.</p>
  </section>
</section>

<section id="security-considerations"><header><span class="section-number">5</span> <h1 data-bookmark-label="5 Security Considerations">Security Considerations</h1><span class="anchor"><a style="text-decoration: none;" href="#security-considerations">¶</a></span></header>


  <p id="security-considerations.1"><a href="#dfn-service-worker">Service workers</a> should be implemented to be HTTPS-only. The reasons for SSL-only support include:</p>
  <ul>
    <li>Better to protect end users from man-in-the-middle attacks</li>
    <li>Do good by encouraging HTTPS adoption</li>
    <li>Existing "playground" services (e.g. github.io) now work with HTTPS</li>
    <li>HTTPS is coming across much more of the web quickly</li>
    <li>Devtools can loosen the restriction for development (file://, localhost, etc.)</li>
  </ul>

  <p class="fixme" id="security-considerations.2">The section will be updated.</p>

  <section id="origin-relativity"><header><span class="section-number">5.1</span> <h1 data-bookmark-label="5.1 Origin Relativity">Origin Relativity</h1><span class="anchor"><a style="text-decoration: none;" href="#origin-relativity">¶</a></span></header>


    <p id="origin-relativity.1">One of the advanced concerns that major applications would encounter is whether they can be hosted from a CDN. By definition, these are servers in other places, often on other domains. Therefore, <a href="#dfn-service-worker">service workers</a> cannot be hosted on CDNs. But they can include resources via <a href="https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-importscripts">importScripts()</a>. The reason for this restriction is that <a href="#dfn-service-worker">service workers</a> create the opportunity for a bad actor to turn a bad day into a bad eternity.</p>
    <p class="fixme" id="origin-relativity.2">The section will be updated.</p>
  </section>

  <section id="cross-origin-resources"><header><span class="section-number">5.2</span> <h1 data-bookmark-label="5.2 Cross-Origin Resources &amp; CORS">Cross-Origin Resources &amp; CORS</h1><span class="anchor"><a style="text-decoration: none;" href="#cross-origin-resources">¶</a></span></header>


    <p id="cross-origin-resources.1">Applications tend to cache items that come from a CDN or other domain. It is possible to request many of them directly using &lt;script&gt;, &lt;img&gt;, &lt;video&gt; and &lt;link&gt; elements. It would be hugely limiting if this sort of runtime collaboration broke when offline. Similarly, it is possible to XHR many sorts of off-domain resources when appropriate CORS headers are set.</p>
    <p id="cross-origin-resources.2">ServiceWorkers enable this by allowing <code><a href="#cache-interface">Cache</a></code>s to fetch and cache off-origin items. Some restrictions apply, however. First, unlike same-origin resources which are managed in the <code><a href="#cache-interface">Cache</a></code> as <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> objects with the <code>type</code> attribute set to "<code>basic</code>", the objects stored are <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> objects with the <code>type</code> attribute set to "<code>opaque</code>". <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>s typed "<code>opaque</code>" provide a much less expressive API than <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>s typed "<code>basic</code>"; the bodies and headers cannot be read or set, nor many of the other aspects of their content inspected. They can be passed to <code><a href="#fetch-event-respondwith-method">event.respondWith(<var>r</var>)</a></code> method and <code>event.forwardTo(<var>url</var>)</code> method in the same manner as the <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>s typed "<code>basic</code>", but cannot be meaningfully created programmatically. These limitations are necessary to preserve the security invariants of the platform. Allowing <code><a href="#cache-interface">Cache</a></code>s to store them allows applications to avoid re-architecting in most cases.</p>
    <p class="fixme" id="cross-origin-resources.3">The section will be updated.</p>
  </section>
</section>

<section id="storage-considerations"><header><span class="section-number">6</span> <h1 data-bookmark-label="6 Storage Considerations">Storage Considerations</h1><span class="anchor"><a style="text-decoration: none;" href="#storage-considerations">¶</a></span></header>


  <p id="storage-considerations.1"><a href="#dfn-service-worker">Service workers</a> should take a dependency on <a href="http://www.w3.org/TR/quota-api/">Quota Management</a> in preparation for an extension event that communicates storage pressure and pre-eviction information to the application.</p>
  <p class="fixme" id="storage-considerations.2">The section will be updated.</p>
</section>

<section id="extensibility"><header><span class="section-number">7</span> <h1 data-bookmark-label="7 Extensibility">Extensibility</h1><span class="anchor"><a style="text-decoration: none;" href="#extensibility">¶</a></span></header>


  <p id="extensibility.1"><a href="#dfn-service-worker">Service workers</a> are extensible from other specifications.</p>

  <section id="extension-to-service-worker-registration"><header><span class="section-number">7.1</span> <h1 data-bookmark-label="7.1 Define API bound to Service Worker Registration">Define API bound to <a href="#extension-to-service-worker-registration">Service Worker Registration</a></h1><span class="anchor"><a style="text-decoration: none;" href="#extension-to-service-worker-registration">¶</a></span></header>

    <p id="extension-to-service-worker-registration.1">Specifications may define an API tied to a <a href="#dfn-service-worker-registration">service worker registration</a> by using <a href="http://heycam.github.io/webidl/#dfn-partial-interface">partial interface</a> definition to the <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> interface where it may define the specification specific attributes and methods:</p>

    <pre><code>partial interface ServiceWorkerRegistration {
  // e.g. define an API namespace
  readonly attribute APISpaceType APISpace;
  // e.g. define a method
  Promise&lt;T&gt; methodName(<em>list of arguments</em>);
};
</code></pre>
  </section>

  <section id="extension-to-extendable-event"><header><span class="section-number">7.2</span> <h1 data-bookmark-label="7.2 Define Functional Event">Define <a href="#extension-to-extendable-event">Functional Event</a></h1><span class="anchor"><a style="text-decoration: none;" href="#extension-to-extendable-event">¶</a></span></header>

    <p id="extension-to-extendable-event.1">Specifications may define a <a href="#dfn-functional-events">functional event</a> by extending <code><a href="#extendable-event-interface">ExtendableEvent</a></code> interface:</p>

    <pre><code>// e.g. define FunctionalEvent interface
interface FunctionalEvent : ExtendableEvent {
  // add a functional event's own attributes and methods
};
</code></pre>
  </section>

  <section id="extension-to-service-worker-global-scope"><header><span class="section-number">7.3</span> <h1 data-bookmark-label="7.3 Define Event Handler">Define <a href="#extension-to-service-worker-global-scope">Event Handler</a></h1><span class="anchor"><a style="text-decoration: none;" href="#extension-to-service-worker-global-scope">¶</a></span></header>

    <p id="extension-to-service-worker-global-scope.1">Specifications may define an event handler attribute for the corresponding <a href="#dfn-functional-events">functional event</a> using <a href="http://heycam.github.io/webidl/#dfn-partial-interface">partial interface</a> definition to the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> interface:</p>

    <pre><code>partial interface ServiceWorkerGlobalScope {
  attribute EventHandler on<em>functionalevent</em>;
};</code></pre>
  </section>

  <section id="request-functional-event-dispatch"><header><span class="section-number">7.4</span> <h1 data-bookmark-label="7.4 Request Functional Event Dispatch">Request <a href="#extension-to-service-worker-global-scope">Functional Event</a> Dispatch</h1><span class="anchor"><a style="text-decoration: none;" href="#request-functional-event-dispatch">¶</a></span></header>

    <p id="request-functional-event-dispatch.1">To request a <a href="#dfn-functional-events">functional event</a> dispatch to a <a href="#dfn-service-worker">service worker</a>, specifications may invoke <a href="#handle-functional-event-algorithm">Handle Functional Event</a> algorithm with its <a href="#dfn-service-worker-registration">service worker registration</a> <var>registration</var> and the algorithm <var>callbackSteps</var> as the arguments.</p>

    <p id="extension-to-service-worker-global-scope.2">Specifications may define an algorithm <var>callbackSteps</var> where the corresponding <a href="#dfn-functional-events">functional event</a> can be created and fired with specification specific objects. The algorithm is passed <var>global object</var> (a <a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a> object) at which it may fire its <a href="#dfn-functional-events">functional events</a>. This algorithm is called on a <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task">task</a> run by <a href="#handle-functional-event-on-scheduled-task-algorithm">Handle Functional Event On Scheduled Task</a> algorithm which is <a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">queued</a> by <a href="#handle-functional-event-algorithm">Handle Functional Event</a> algorithm.</p>

    <p class="note" id="extension-to-service-worker-global-scope.3">See an <a href="https://notifications.spec.whatwg.org/#activating-a-notification">example</a> hook defined in <a href="https://notifications.spec.whatwg.org">Notifications API</a>.</p>
  </section>
</section>

<section id="algorithms"><header><span class="section-number">8</span> <h1 data-bookmark-label="8 Appendix A: Algorithms">Appendix A: Algorithms</h1><span class="anchor"><a style="text-decoration: none;" href="#algorithms">¶</a></span></header>


  <p id="algorithms.1">The double square bracket notation (<strong>[[</strong><em>name of method</em> or <em>name of property</em><strong>]]</strong>) is used throughout the specification to indicate user agent's internal data structures.</p>
  <div class="algorithm">
  <p><dfn id="scope-to-registration-map">[[ScopeToRegistrationMap]]</dfn> represents an internal map structure that stores the entries of the Record {[[key]], [[value]]} where [[key]] is a string that represents a <a href="#dfn-scope-url">scope url</a> and [[value]] is a <a href="#dfn-service-worker-registration">service worker registration</a>.</p>

  <p><dfn id="request-to-response-map">[[RequestToResponseMap]]</dfn> represents an internal map structure that stores the entries of the Record {[[key]], [[value]]} where [[key]] is a <code><a href="https://fetch.spec.whatwg.org/#request">Request</a></code> and [[value]] is a <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>.</p>

  <p><dfn id="name-to-cache-map">[[NameToCacheMap]]</dfn> represents an internal map structure that stores the entries of the Record {[[key]], [[value]]} where [[key]] is a string that represents a name of the <code><a href="#cache-interface">Cache</a></code> object and [[value]] is a <code><a href="#cache-interface">Cache</a></code> object.</p>

  <p>An <dfn id="dfn-algorithm-task-queue">algorithm thread queue</dfn> is a thread safe queue used to synchronize the set of concurrent entries of algorithm steps. The queue contains <a href="http://en.wikipedia.org/wiki/Timestamping_(computing)">timestamps</a> (with <a href="http://en.wikipedia.org/wiki/Timestamp-based_concurrency_control#Assumptions">the assumptions</a>), gained by algorithms, as its elements. The queue should satisfy the general properties of FIFO queue.</p>

  <p><dfn id="registration-queue-adt">[[RegistrationQueue]]</dfn> is  an <a href="#dfn-algorithm-task-queue">algorithm thread queue</a> for synchronizing the set of concurrent registration requests. The user agent must maintain a separate queue for each <a href="#dfn-service-worker-registration">service worker registration</a> keyed by its <a href="#dfn-scope-url">scope url</a>. The queue is initially empty.</p>

  <p><dfn id="installation-queue-adt">[[InstallationQueue]]</dfn> is an <a href="#dfn-algorithm-task-queue">algorithm thread queue</a> for synchronizing the set of concurrent installation jobs. The user agent must maintain a separate queue for each <a href="#dfn-service-worker-registration">service worker registration</a> keyed by its <a href="#dfn-scope-url">scope url</a>. The queue is initially empty.</p>

  <p><dfn id="installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</dfn> is an <a href="#dfn-algorithm-task-queue">algorithm thread queue</a> for synchronizing the set of concurrent installation jobs. The user agent must maintain a separate queue for each <a href="#dfn-service-worker-registration">service worker registration</a> keyed by its <a href="#dfn-scope-url">scope url</a>. The queue is initially empty.</p>
  </div>

  <section id="register-algorithm"><header><span class="section-number">8.1</span> <h1 data-bookmark-label="8.1 Register">Register</h1><span class="anchor"><a style="text-decoration: none;" href="#register-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>document</var>, a <a href="https://html.spec.whatwg.org/multipage/dom.html#the-document-object"><code>Document</code></a></dd>
        <dd><var>scriptURL</var>, a string that represents the URL of the script</dd>
        <dd><var>scope</var>, a <a href="https://url.spec.whatwg.org/#concept-relative-url">relative URL</a> that represents a path prefix of a <a href="#dfn-scope-url">scope url</a></dd>
        <dd><var>base</var>, a <a href="https://url.spec.whatwg.org/#concept-base-url">base URL</a>, optional</dd>
      <dt>Output</dt>
        <dd><var>promise</var>, a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a></dd>
    </dl>
    <ol>
      <li>Let <var>scope</var> be the result of running the <a href="https://url.spec.whatwg.org/#concept-url-parser">URL parser</a> on <var>scope</var> with <var>base</var>.</li>
      <li>Set <var>scope</var> to the result of running the <a href="https://url.spec.whatwg.org/#concept-url-serializer">URL serializer</a> on <var>scope</var> with the <em>exclude fragment flag</em> set.</li>
      <li>Let <var>scriptURL</var> be the result of running the <a href="https://url.spec.whatwg.org/#concept-url-parser">URL parser</a> on <var>scriptURL</var> with <var>base</var>.</li>
      <li>If the result of running <a href="http://www.w3.org/TR/2014/WD-mixed-content-20140916/#is-origin-authenticated">Is origin authenticated origin</a> with the <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> of <var>scriptURL</var> as the argument is unauthenticated, then:
        <ol>
          <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
        </ol>
      </li>
      <li>If the <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> of <var>scriptURL</var> does not match <var>document</var>'s <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>, then:
        <ol>
          <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
        </ol>
      </li>
      <li>If the <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> of <var>scope</var> does not match <var>document</var>'s <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>, then:
        <ol>
          <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> rejected with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
        </ol>
      </li>
      <li>Run the following substeps atomically:
        <ol>
          <li>Let <var>registration</var> be the result of running the <a href="#get-registration-algorithm">Get Registration</a> algorithm passing <var>scope</var> as the argument.</li>

          <li>If <var>registration</var> is not null, then:
            <ol>
              <li>Let <var>newestWorker</var> be the result of running the <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm passing <var>registration</var> as the argument.</li>
              <li>If <var>newestWorker</var> is not null, <var>scriptURL</var> is equal to <var>newestWorker</var>'s <a href="#dfn-script-url">script url</a>, and <var>scriptURL</var> is equal to <var>registration</var>'s <a href="#dfn-registration-script-url">registering script url</a>, then:
                <ol>
                  <li>If <var>newestWorker</var> is an <a href="#dfn-active-worker">active worker</a>, then:
                    <ol>
                      <li>If <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a> is set, unset it.</li>
                      <li>Return a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolved with a <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> object that represents <var>registration</var>.</li>
                    </ol>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Set <var>registration</var> to the result of running <a href="#set-registration-algorithm">Set Registration</a> algorithm passing <var>scope</var> as its argument.</li>
            </ol>
          </li>
          <li>Set <var>registration</var>'s <a href="#dfn-registration-script-url">registering script url</a> to <var>scriptURL</var>.</li>
          <li>Return the result of running the <a href="#update-algorithm">Update</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, passing <var>registration</var> as the argument.</li>
        </ol>
      </li>
    </ol>
    </div>
  </section>

  <section id="update-algorithm"><header><span class="section-number">8.2</span> <h1 data-bookmark-label="8.2 Update">Update</h1><span class="anchor"><a style="text-decoration: none;" href="#update-algorithm">¶</a></span></header>


    <p id="update-algorithm.1">The algorithm uses <a href="#registration-queue-adt">[[RegistrationQueue]]</a> to synchronize the set of multiple registration requests. Implementers may use it or other synchronization primitives and methods to satisfy this requirement.</p>

  <!--
  #FIXME: (Checkpoint) This is a platform implmentation not exposing APIs to userland. As such, promise is not used for its output.
  -->
    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
      <dt>Output</dt>
        <dd><var>promise</var>, a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a></dd>
    </dl>
    <ol>
      <li>Let <var>p</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
      <li><a href="http://en.wikipedia.org/wiki/Timestamp-based_concurrency_control#Generating_a_Timestamp">Generate a timestamp</a> and let <var>timeStamp</var> be the result value.</li>
      <li>Push <var>timeStamp</var> to <a href="#registration-queue-adt">[[RegistrationQueue]]</a>, <a href="#installation-queue-adt">[[InstallationQueue]]</a>, and <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
      <li>Run the following substeps in parallel:
        <ol>
          <li><em>CheckPriority</em>: If the value of the top element of <a href="#registration-queue-adt">[[RegistrationQueue]]</a> matches <var>timeStamp</var>, then:
            <ol>
              <li>Pop the top element from <a href="#registration-queue-adt">[[RegistrationQueue]]</a>.</li>
            </ol>
          </li>
          <li>Else:
            <ol>
              <li>Wait until the top element of <a href="#registration-queue-adt">[[RegistrationQueue]]</a> is popped.</li>
              <li>Jump to the step labeled <em>CheckProirity</em>.</li>
            </ol>
            <p class="note"><em>Wait</em> is a blocking wait. Implementers may use a condition variable or its equivalent synchronization primitive.</p>
          </li>
          <li>Run the following substeps atomically:
            <ol>
              <li>If <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> is not null, then:
                <ol>
                  <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
                  <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> and <em>redundant</em> as the arguments.</li>
                  <li>Set <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> to null.</li>
                  <li>The user agent may abort in-flight requests triggered by <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
                </ol>
              </li>
              <li>Let <var>r</var> be the associated <a href="https://fetch.spec.whatwg.org/#concept-request">request</a> of the result of invoking the initial value of <a href="https://fetch.spec.whatwg.org/#dom-request">Request</a> as constructor with <var>registration</var>'s <a href="#dfn-registration-script-url">registering script url</a>. If this throws an exception, then:
                <ol>
                  <li>Reject <var>p</var> with the exception.</li>
                  <li>Pop the top element from <a href="#installation-queue-adt">[[InstallationQueue]]</a> and <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
                  <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                    <ol>
                      <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                    </ol>
                  </li>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> to <em>serviceworker</em>.</li>
              <li>Append `<code>Service-Worker</code>`/`<code>script</code>` to <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-header-list">header list</a>.</li>
              <li>Set <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#skip-service-worker-flag">skip service worker flag</a> and <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#synchronous-flag">synchronous flag</a>.</li>
              <li>Let <var>response</var> be the result of running <a href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</a> using <var>r</var>, forcing a network fetch if cached entry is greater than 1 day old.</li>
              <li>If <var>response</var> is a <a href="https://fetch.spec.whatwg.org/#concept-network-error">network error</a>, then:
                <ol>
                  <li>If <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-redirect-count">redirect count</a> is not zero, then:
                    <ol>
                      <li>Reject <var>p</var> with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
                      <li>Pop the top element from <a href="#installation-queue-adt">[[InstallationQueue]]</a> and <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
                      <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                        <ol>
                          <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                        </ol>
                      </li>
                      <li>Abort these steps.</li>
                    </ol>
                  </li>
                  <li>Else:
                    <ol>
                      <li>Reject <var>p</var> with a "<code><a href="http://heycam.github.io/webidl/#networkerror">NetworkError</a></code>" exception.</li>
                      <li>Pop the top element from <a href="#installation-queue-adt">[[InstallationQueue]]</a> and <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
                      <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                        <ol>
                          <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                        </ol>
                      </li>
                      <li>Abort these steps.</li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li><a href="https://fetch.spec.whatwg.org/#concept-header-extract-mime-type">Extract a MIME type</a> from the <var>response</var>'s <a href="https://fetch.spec.whatwg.org/#concept-response-header-list">header list</a>. If this MIME type (ignoring parameters) is not one of <code>text/javascript</code>, <code>application/x-javascript</code>, or <code>application/javascript</code>, then:
                <ol>
                  <li>Reject <var>p</var> with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
                  <li>Pop the top element from <a href="#installation-queue-adt">[[InstallationQueue]]</a> and <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
                  <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                    <ol>
                      <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                    </ol>
                  </li>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Let <var>newestWorker</var> be the result of running the <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm passing <var>registration</var> as the argument.</li>
              <li>If <var>newestWorker</var> is not null, and <var>newestWorker</var>'s <a href="#dfn-script-url">script url</a> is equal to <var>registration</var>'s <a href="#dfn-registration-script-url">registering script url</a> and <var>response</var> is a byte-for-byte match with the script of <var>newestWorker</var>, then:
                <ol>
                  <li>Resolve <var>p</var> with <var>registration</var>.</li>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Else:
                <ol>
                  <li>Let <var>worker</var> be a new <a href="#dfn-service-worker">service worker</a> for the script with <var>registration</var>'s <a href="#dfn-registration-script-url">registering script url</a>.</li>
                  <li>If <var>worker</var> fails to start up, due to parse errors or uncaught errors, then:
                    <ol>
                      <li>Reject <var>p</var> with the error.</li>
                      <li>Pop the top element from <a href="#installation-queue-adt">[[InstallationQueue]]</a> and <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
                      <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                        <ol>
                          <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                        </ol>
                      </li>
                      <li>Abort these steps.</li>
                    </ol>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Invoke <a href="#installation-algorithm">Install</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var>, <var>worker</var>, <var>p</var>, and <var>timeStamp</var> as its arguments.</li>
        </ol>
      </li>
      <li>Return <var>p</var>.</li>
    </ol>
    </div>
  </section>

  <section id="soft-update-algorithm"><header><span class="section-number">8.3</span> <h1 data-bookmark-label="8.3 Soft Update">Soft Update</h1><span class="anchor"><a style="text-decoration: none;" href="#soft-update-algorithm">¶</a></span></header>


    <p id="soft-update-algorithm.1">The user agent may call this as often as it likes to check for updates.</p>

    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
      <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li>If <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a> is set, then:
        <ol>
          <li>Abort these steps.</li>
        </ol>
      </li>
      <li>If <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> is not null, then:
        <ol>
          <li>Abort these steps.</li>
        </ol>
      </li>
      <li>Invoke <a href="#update-algorithm">Update</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var> as its argument.</li>
    </ol>
    </div>
    <p class="fixme" id="soft-update-algorithm.2">Inspect whether the <var>promise</var> returned from <a href="#update-algorithm">Update</a> algorithm should be returned to the caller (either UA internal context or <code><a href="#service-worker-global-scope-update-method">self.update()</a></code>).</p>
  </section>

  <section id="installation-algorithm"><header><span class="section-number">8.4</span> <h1 data-bookmark-label="8.4 Install">Install</h1><span class="anchor"><a style="text-decoration: none;" href="#installation-algorithm">¶</a></span></header>


    <p id="installation-algorithm.1">The algorithm uses <a href="#installation-queue-adt">[[InstallationQueue]]</a> to synchronize the set of multiple installation jobs. Implementers may use it or other synchronization primitives and methods to satisfy this requirement.</p>

    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
        <dd><var>worker</var>, a <a href="#dfn-service-worker">service worker</a></dd>
        <dd><var>registrationPromise</var>, a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a></dd>
        <dd><var>timeStamp</var>, a <a href="http://en.wikipedia.org/wiki/Timestamping_(computing)">timestamp</a></dd>
      <dt>Output</dt>
        <dd>none</dd>
    </dl>
    <ol>
      <li>Let <var>installFailed</var> be false.</li>
      <li><em>CheckPriority</em>: If the value of the top element of <a href="#installation-queue-adt">[[InstallationQueue]]</a> matches <var>timeStamp</var>, then:
        <ol>
          <li>Pop the top element from <a href="#installation-queue-adt">[[InstallationQueue]]</a>.</li>
        </ol>
      </li>
      <li>Else:
        <ol>
          <li>Wait until the top element of <a href="#installation-queue-adt">[[InstallationQueue]]</a> is popped.</li>
          <li>Jump to the step labeled <em>CheckProirity</em>.</li>
        </ol>
        <p class="note"><em>Wait</em> is a blocking wait. Implementers may use a condition variable or its equivalent synchronization primitive.</p>
      </li>
      <li>Run the following substeps atomically:
        <ol>
          <li>If <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> is not null, then:
            <ol>
              <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
              <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> and <em>redundant</em> as the arguments.</li>
              <li>The user agent may abort any in-flight requests triggered by <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
            </ol>
          </li>
          <li>Set <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> to <var>worker</var>.</li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> and <em>installing</em> as the arguments.</li>
          <li><a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-algorithm-conventions">Assert</a>: <var>registrationPromise</var> is not null.</li>
          <li>Resolve <var>registrationPromise</var> with <var>registration</var>.</li>
          <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to <a href="https://html.spec.whatwg.org/#fire-a-simple-event">fire a simple event named</a> <code>updatefound</code> at all the <code><a href="#service-worker-registration-interface">ServiceWorkerRegistration</a></code> objects associated with <var>registration</var> for all the <a href="#dfn-service-worker-client">service worker clients</a> which use <var>registration</var>.</li>
          <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to run the following substeps:
            <ol>
              <li>Let <var>installingWorker</var> be <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
              <li><a href="https://html.spec.whatwg.org/multipage/workers.html#run-a-worker">Run a worker</a>, if not running, for a script with <var>installingWorker</var>'s <a href="#dfn-script-url">script url</a> and <var>installingWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>.</li>
              <li><a href="https://dom.spec.whatwg.org/#concept-event-fire">Fire an event</a> named <code>install</code> using <a href="#install-event-interface">InstallEvent</a> interface at <var>installingWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a>.</li>
              <li>For each <a href="https://dom.spec.whatwg.org/#concept-event-listener">event listener</a> <a href="https://dom.spec.whatwg.org/#concept-event-listener-invoke">invoked</a>:
                <ol>
                  <li>If any uncaught runtime script error occurs, then:
                    <ol>
                      <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#report-the-error">Report the error</a> for the script per the <a href="https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2">runtime script errors handling</a>.</li>
                      <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> and <em>redundant</em> as the arguments.</li>
                      <li>Set <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> to null.</li>
                      <li>Pop the top element from <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
                      <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                        <ol>
                          <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                        </ol>
                      </li>
                      <li>Abort these steps.</li>
                    </ol>
                  </li>
                  <li>Let <var>event</var> be the event for which this <a href="https://dom.spec.whatwg.org/#concept-event-listener">event listener</a> was invoked.</li>
                  <li>If <var>event</var>'s <a href="#extend-lifetime-flag">extend lifetime flag</a> is set, then:
                    <ol>
                      <li>Wait until <var>event</var>'s <a href="#extend-lifetime-flag">extend lifetime flag</a> is unset.</li>
                      <li>If <var>event</var>'s <a href="#wait-until-reject-flag">wait-until reject flag</a> is set, then:
                        <ol>
                          <li>Set <var>installFailed</var> to true.</li>
                        </ol>
                      </li>
                    </ol>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
        </ol>
      </li>
      <li><em>CheckResultHandlePriority</em>: If the value of the top element of <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a> matches <var>timeStamp</var>, then:
        <ol>
          <li>Pop the top element from <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a>.</li>
        </ol>
      </li>
      <li>Else:
        <ol>
          <li>Wait until the top element of <a href="#installation-result-handle-queue-adt">[[InstallationResultHandleQueue]]</a> is popped.</li>
          <li>Jump to the step labeled <em>CheckResultHandlePriority</em>.</li>
        </ol>
        <p class="note"><em>Wait</em> is a blocking wait. Implementers may use a condition variable or its equivalent synchronization primitive.</p>
      </li>
      <li>Run the following substeps atomically:
        <ol>
          <li>Wait for the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task">task</a> queued by the step 4.7 to have executed.</li>
          <li>If <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> is null, then:
            <ol>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>If <var>installFailed</var> is true, then:
            <ol>
              <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> and <em>redundant</em> as the arguments.</li>
              <li>Set <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> to null.</li>
              <li>If the result of running <a href="#get-newest-worker-algorithm">Get Newest Worker</a> algorithm is null, then:
                <ol>
                  <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
                </ol>
              </li>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>If <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> is not null, then:
            <ol>
              <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>.</li>
              <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> and <em>redundant</em> as the arguments.</li>
              <li>The user agent may abort in-flight requests triggered by <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>.</li>
            </ol>
          </li>
          <li>Set <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> to <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
          <li>Set <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> to null.</li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> and <em>installed</em> as the arguments.</li>
          <li>If <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a> is set before <var>timeStamp</var>, then:
            <ol>
              <li>Wait until a Record {[[key]], [[value]]} <var>entry</var> of its <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a> where <var>registration</var>'s <a href="#dfn-scope-url">scope url</a> matches <var>entry</var>.[[key]] is deleted.</li>
              <li>Set a newly-created Record {[[key]]: <var>registration</var>'s <a href="#dfn-scope-url">scope url</a>, [[value]]: <var>registration</var>} to <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a>.</li>
              <li>Unset <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a>.</li>
            </ol>
          </li>
          <li>If <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>'s <a href="#dfn-skip-waiting-flag">skip waiting flag</a> is set, then:
            <ol>
              <li>For each <a href="#dfn-service-worker-client">service worker client</a> <var>client</var> whose <a href="#dfn-client-url">client url</a> <a href="#scope-match-algorithm">matches</a> <var>registration</var>'s <a href="#dfn-scope-url">scope url</a>:
                <ol>
                  <li>Let <var>exitingWorker</var> be the <a href="#dfn-active-worker">active worker</a> that <a href="#dfn-control">controls</a> <var>client</var>.</li>
                  <li>If <var>exitingWorker</var> is not null, then:
                    <ol>
                      <li>Wait for <var>exitingWorker</var> to finish handling any in-progress requests.
                      </li>
                      <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>exitingWorker</var>.</li>
                      <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>exitingWorker</var> and <em>redundant</em> as the arguments.</li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li>Run <a href="#activation-algorithm">Activate</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, passing <var>registration</var> as the argument.</li>
              <li>Abort these steps.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Wait until no <a href="#dfn-service-worker-client">service worker client</a> is <a href="#dfn-use">using</a> <var>registration</var> as their <a href="#dfn-service-worker-registration">service worker registration</a>.</li>
      <li>Invoke <a href="#activation-algorithm">Activate</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var> as its argument.</li>
    </ol>
    </div>
  </section>

  <section id="activation-algorithm"><header><span class="section-number">8.5</span> <h1 data-bookmark-label="8.5 Activate">Activate</h1><span class="anchor"><a style="text-decoration: none;" href="#activation-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
      <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li>Run the following substeps atomically:
        <ol>
          <li>Let <var>activateFailed</var> be false.</li>
          <li>Let <var>activatingWorker</var> be <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>.</li>
          <li>Let <var>exitingWorker</var> be <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
          <li>If <var>activatingWorker</var> is null, then:
            <ol>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>If <var>exitingWorker</var> is not null, then:
            <ol>
              <li>Wait for <var>exitingWorker</var> to finish handling any in-progress requests.
              </li>
              <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>exitingWorker</var>.</li>
              <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>exitingWorker</var> and <em>redundant</em> as the arguments.</li>
            </ol>
          </li>
          <li>Set <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> to <var>activatingWorker</var>.</li>
          <li>Set <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> to null.</li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> and <em>activating</em> as the arguments.</li>
          <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to <a href="https://html.spec.whatwg.org/#fire-a-simple-event">fire a simple event named</a> <code>controllerchange</code> at all the <code><a href="#service-worker-container-interface">ServiceWorkerContainer</a></code> objects for all the <a href="#dfn-service-worker-client">service worker clients</a> which use <var>registration</var>.</li>
          <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to run the following substeps:
            <ol>
              <li>Let <var>activeWorker</var> be <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
              <li><a href="https://html.spec.whatwg.org/multipage/workers.html#run-a-worker">Run a worker</a>, if not running, for a script with <var>activeWorker</var>'s <a href="#dfn-script-url">script url</a> and <var>activeWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>.</li>
              <li><a href="https://dom.spec.whatwg.org/#concept-event-fire">Fire an event</a> named <code>activate</code> using <a href="#extendable-event-interface">ExtendableEvent</a> interface at <var>activeWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a>.</li>
              <li>For each <a href="https://dom.spec.whatwg.org/#concept-event-listener">event listener</a> <a href="https://dom.spec.whatwg.org/#concept-event-listener-invoke">invoked</a>:
                <ol>
                  <li>If any uncaught runtime script error occurs, then:
                    <ol>
                      <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#report-the-error">Report the error</a> for the script per the <a href="https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2">runtime script errors handling</a>.</li>
                      <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> and <em>redundant</em> as the arguments.</li>
                      <li>Set <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> to null.</li>
                      <li>Abort these steps.</li>
                    </ol>
                  </li>
                  <li>Let <var>event</var> be the event for which this <a href="https://dom.spec.whatwg.org/#concept-event-listener">event listener</a> was invoked.</li>
                  <li>If <var>event</var>'s <a href="#extend-lifetime-flag">extend lifetime flag</a> is set, then:
                    <ol>
                      <li>Wait until <var>event</var>'s <a href="#extend-lifetime-flag">extend lifetime flag</a> is unset.</li>
                      <li>If <var>event</var>'s <a href="#wait-until-reject-flag">wait-until reject flag</a> is set, then:
                        <ol>
                          <li>Set <var>activateFailed</var> to true.</li>
                        </ol>
                      </li>
                    </ol>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
          <li>Wait for the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task">task</a> queued by the previous step to have executed.</li>
          <li>If <var>activateFailed</var> is true, then:
            <ol>
              <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> and <em>redundant</em> as the arguments.</li>
              <li>Set <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> to null.</li>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> and <em>activated</em> as the arguments.</li>
        </ol>
      </li>
    </ol>
    </div>
  </section>

  <section id="on-fetch-request-algorithm"><header><span class="section-number">8.6</span> <h1 data-bookmark-label="8.6 Handle Fetch">Handle Fetch</h1><span class="anchor"><a style="text-decoration: none;" href="#on-fetch-request-algorithm">¶</a></span></header>


    <p id="on-fetch-request-algorithm.1">The <a href="#on-fetch-request-algorithm">Handle Fetch</a> algorithm is the entry point for the <a href="https://fetch.spec.whatwg.org/#concept-fetch">fetch</a> handling handed to the <a href="#dfn-service-worker">service worker</a> context.</p>

    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>request</var>, a <a href="https://fetch.spec.whatwg.org/#concept-request">request</a></dd>
      <dt>Output</dt>
        <dd><var>response</var>, a <a href="https://fetch.spec.whatwg.org/#concept-response">response</a></dd>
    </dl>
    <ol>
      <li>Let <var>handleFetchFailed</var> be false.</li>
      <li>Let <var>respondWithEntered</var> be false.</li>
      <li>Let <var>r</var> be a new <code><a href="https://fetch.spec.whatwg.org/#request">Request</a></code> object associated with <var>request</var>.</li>
      <li>Let <var>headersObject</var> be <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#dom-request-headers">headers</a> attribute value.</li>
      <li>Set <var>headersObject</var>'s <a href="https://fetch.spec.whatwg.org/#concept-headers-guard">guard</a> to <em>immutable</em>.</li>
      <li>Let <var>response</var> be null.</li>
      <li>Let <var>registration</var> be null.</li>
      <li>Let <var>client</var> be null.</li>
      <li>Assert: <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-client">client</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a> is either a <a href="https://html.spec.whatwg.org/multipage/browsers.html#window">Window</a> object or a <a href="https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope">SharedWorkerGlobalScope</a> object.</li>
      <li>If <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-client">client</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a> is a <a href="https://html.spec.whatwg.org/multipage/browsers.html#window">Window</a> object, then:
        <ol>
          <li>Set <var>client</var> to the <a href="https://html.spec.whatwg.org/multipage/browsers.html#concept-document-window">associated</a> <a href="https://dom.spec.whatwg.org/#concept-document">document</a> of <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-client">client</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a>.</li>
        </ol>
      </li>
      <li>Else if <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-client">client</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a> is a <a href="https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope">SharedWorkerGlobalScope</a> object, then:
        <ol>
          <li>Set <var>client</var> to the shared worker represented by <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-client">client</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a>.</li>
        </ol>
      </li>
      <li>Assert: <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is not <em>serviceworker</em>.</li>
      <li>If <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is either <em>embed</em> or <em>object</em>, then:
        <ol>
          <li>Return null.</li>
        </ol>
      </li>
      <li>Else if <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is one of <em>frame</em>, <em>hyperlink</em>, <em>iframe</em>, <em>location</em>, and <em>sharedworker</em>, then:
        <ol>
          <li>If the <a href="https://html.spec.whatwg.org/multipage/browsers.html#navigate">navigation</a> triggering <var>request</var> was initiated with a shift+reload or equivalent, then:
            <ol>
              <li>Return null.</li>
            </ol>
          </li>
          <li>Set <var>registration</var> to the result of running <a href="#scope-match-algorithm">Match Scope</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, passing <var>r</var>.<var>url</var> as the argument.</li>
        </ol>
      </li>
      <li>Else:
        <ol>
          <li>If <var>client</var> is a <a href="#dfn-service-worker-client">service worker client</a>, then:
            <ol>
              <li>Set <var>registration</var> to <var>client</var>'s <a href="#dfn-service-worker-registration">service worker registration</a>.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>If <var>registration</var> is null, then:
        <ol>
          <li>Return null.</li>
        </ol>
      </li>
      <li>If <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> is null, then:
        <ol>
          <li>Return null.</li>
        </ol>
      </li>
      <li>Let <var>matchedWorker</var> be <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
      <li>Assert: <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is not <em>serviceworker</em>, <em>embed</em>, or <em>object</em>.</li>
      <li>If <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is one of <em>frame</em>, <em>hyperlink</em>, <em>iframe</em>, <em>location</em>, and <em>sharedworker</em>, then:
        <ol>
          <li>Let <var>client</var> <a href="#dfn-use">use</a> <var>registration</var> as its <a href="#dfn-service-worker-registration">service worker registration</a>.</li>
        </ol>
      </li>
      <li>If <var>matchedWorker</var>'s <a href="#dfn-state">state</a> is <em>activating</em>, then:
        <ol>
          <li>Wait for <var>matchedWorker</var>'s <a href="#dfn-state">state</a> to become <em>activated</em>.</li>
          <li>If <var>matchedWorker</var>'s activation fails, then:
            <ol>
              <li>Return null.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to run the following substeps:
        <ol>
          <li>Let <var>activeWorker</var> be <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
          <li><a href="https://html.spec.whatwg.org/multipage/workers.html#run-a-worker">Run a worker</a>, if not running, for a script with <var>activeWorker</var>'s <a href="#dfn-script-url">script url</a> and <var>activeWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>.</li>
          <li><a href="https://dom.spec.whatwg.org/#concept-event-fire">Fire an event</a> named <code>fetch</code>, using <a href="#fetch-event-interface">FetchEvent</a> interface, with <var>request</var> attribute initialized to <var>r</var>, <var>client</var> attribute initialized to <a href="https://fetch.spec.whatwg.org/#concept-request-client">client</a> of the <var>request</var>, in the form of <a href="#service-worker-client-interface">ServiceWorkerClient</a> object, and <var>isReload</var> initialized to <code>true</code> if event was dispatched with the user's intention for the page reload, and <code>false</code> otherwise, at <var>activeWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a>.</li>
          <li>For each <a href="https://dom.spec.whatwg.org/#concept-event-listener">event listener</a> <a href="https://dom.spec.whatwg.org/#concept-event-listener-invoke">invoked</a>:
            <ol>
              <li>If any uncaught runtime script error occurs, then:
                <ol>
                  <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#report-the-error">Report the error</a> for the script per the <a href="https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2">runtime script errors handling</a>.</li>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Let <var>event</var> be the event for which this <a href="https://dom.spec.whatwg.org/#concept-event-listener">event listener</a> was invoked.</li>
              <li>If <var>event</var>'s <a href="#respond-with-entered-flag">respond-with entered flag</a> is set, then:
                <ol>
                  <li>Set <var>respondWithEntered</var> to true.</li>
                </ol>
              </li>
              <li>If <var>event</var>'s <a href="#wait-to-respond-flag">wait to respond flag</a> is set, then:
                <ol>
                  <li>Wait until <var>event</var>'s <a href="#wait-to-respond-flag">wait to respond flag</a> is unset.</li>
                  <li>If <var>event</var>'s <a href="#respond-with-error-flag">respond-with error flag</a> is set, then:
                    <ol>
                      <li>Set <var>handleFetchFailed</var> to true.</li>
                    </ol>
                  </li>
                  <li>Else:
                    <ol>
                      <li>Set <var>response</var> to the value, which the argument passed into the <var>event</var>'s <code><a href="#fetch-event-respondwith-method">respondWith(<var>r</var>)</a></code> method resolved with.</li>
                    </ol>
                  </li>
                </ol>
              </li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Wait for the <a href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task">task</a> queued by the previous step to have executed.</li>
      <li>If <var>respondWithEntered</var> is false, then:
        <ol>
          <li>Return null and run the following substeps in parallel.</li>
          <li>If <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is one of <em>frame</em>, <em>hyperlink</em>, <em>iframe</em>, <em>location</em>, and <em>sharedworker</em>, then:
            <ol>
              <li>Invoke <a href="#soft-update-algorithm">Soft Update</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var>.</li>
            </ol>
          </li>
          <li>Abort these steps.</li>
        </ol>
      </li>
      <li>If <var>handleFetchFailed</var> is true, then:
        <ol>
          <li>Return a <a href="https://fetch.spec.whatwg.org/#concept-network-error">network error</a> and run the following substeps in parallel.</li>
          <li>If <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is one of <em>frame</em>, <em>hyperlink</em>, <em>iframe</em>, <em>location</em>, and <em>sharedworker</em>, then:
            <ol>
              <li>Invoke <a href="#soft-update-algorithm">Soft Update</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var>.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Else:
        <ol>
          <li>Return a <a href="https://fetch.spec.whatwg.org/#concept-response">response</a> represented by <var>response</var> and run the following substeps in parallel.</li>
          <li>If <var>request</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-context">context</a> is one of <em>frame</em>, <em>hyperlink</em>, <em>iframe</em>, <em>location</em>, and <em>sharedworker</em>, then:
            <ol>
              <li>Invoke <a href="#soft-update-algorithm">Soft Update</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var>.</li>
            </ol>
          </li>
        </ol>
      </li>
    </ol>
    </div>
  </section>

  <section id="handle-functional-event-algorithm"><header><span class="section-number">8.7</span> <h1 data-bookmark-label="8.7 Handle Functional Event">Handle Functional Event</h1><span class="anchor"><a style="text-decoration: none;" href="#handle-functional-event-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
    <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
        <dd><var>callbackSteps</var>, an algorithm</dd>
    <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to run <a href="#handle-functional-event-on-scheduled-task-algorithm">Handle Functional Event On Scheduled Task</a> algorithm with <var>registration</var> and <var>callbackSteps</var>.</li>
    </ol>
    </div>
    <p class="fixme" id="handle-functional-event-algorithm.1">Event loop and task queuing model for this algorithm will be specified.</p>
  </section>

  <section id="handle-functional-event-on-scheduled-task-algorithm"><header><span class="section-number">8.8</span> <h1 data-bookmark-label="8.8 Handle Functional Event On Scheduled Task">Handle Functional Event On Scheduled Task</h1><span class="anchor"><a style="text-decoration: none;" href="#handle-functional-event-on-scheduled-task-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
    <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
        <dd><var>callbackSteps</var>, an algorithm</dd>
    <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li><a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-algorithm-conventions">Assert</a>: a Record with the [[value]] equals to <var>registration</var> is contained in <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a>.</li>
      <li><a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-algorithm-conventions">Assert</a>: <var>registration</var>'s active worker is not null.</li>
      <li>Let <var>activeWorker</var> be <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
      <li><a href="https://html.spec.whatwg.org/multipage/workers.html#run-a-worker">Run a worker</a>, if not running, for a script with <var>activeWorker</var>'s <a href="#dfn-script-url">script url</a> and <var>activeWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>.</li>
      <li>Invoke <var>callbackSteps</var>, defined by the caller of the algorithm which <a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">queued this task</a>, with <var>activeWorker</var>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object"> environment settings object</a>'s <a href="https://html.spec.whatwg.org/multipage/webappapis.html#global-object">global object</a> as its argument.</li>
      <li>Return.</li>
    </ol>
    </div>
  </section>

  <section id="on-document-unload-algorithm"><header><span class="section-number">8.9</span> <h1 data-bookmark-label="8.9 Handle Document Unload">Handle Document Unload</h1><span class="anchor"><a style="text-decoration: none;" href="#on-document-unload-algorithm">¶</a></span></header>


    <p id="on-document-unload-algorithm.1">The user agent must run these steps, or their <a href="#dfn-processing-equivalence">equivalent</a>, when it <a href="https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document">unloads a document</a>.</p>

    <div class="algorithm">
    <dl>
    <dt>Input</dt>
        <dd><var>document</var>, a document <a href="#dfn-use">using</a> the <a href="#dfn-service-worker-registration">service worker registration</a></dd>
    <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li>Run the following steps atomically.</li>
      <li>Let <var>registration</var> be the <a href="#dfn-service-worker-registration">service worker registration</a> <a href="#dfn-use">used</a> by <var>document</var>.</li>
      <li>If <var>registration</var> is null, then:
        <ol>
          <li>Abort these steps.</li>
        </ol>
      </li>
      <li>If any other document is <a href="#dfn-use">using</a> <var>registration</var> as their <a href="#dfn-service-worker-registration">service worker registration</a>, then:
        <ol>
          <li>Abort these steps.</li>
        </ol>
      </li>
      <li>If <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a> is true, then:
        <ol>
          <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
          <li>Abort these steps.</li>
        </ol>
      </li>
      <li>If <var>registration</var>.<var>waiting</var> is not null:
        <ol>
          <li>Run <a href="#activation-algorithm">Activate</a> algorithm, or its <a href="#dfn-processing-equivalence">equivalent</a>, with <var>registration</var> at the argument.</li>
        </ol>
      </li>
    </ol>
    </div>
  </section>

  <section id="unregister-algorithm"><header><span class="section-number">8.10</span> <h1 data-bookmark-label="8.10 Unregister">Unregister</h1><span class="anchor"><a style="text-decoration: none;" href="#unregister-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>document</var>, a <a href="https://html.spec.whatwg.org/multipage/dom.html#the-document-object"><code>Document</code></a></dd>
        <dd><var>scope</var>, a <a href="#dfn-scope-url">scope url</a></dd>
      <dt>Output</dt>
        <dd><var>promise</var>, a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a></dd>
    </dl>
    <ol>
      <li>Let <var>promise</var> be a new <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a>.</li>
      <li>Let <var>scope</var> to the result of running the <a href="https://url.spec.whatwg.org/#concept-url-serializer">URL serializer</a> on <var>scope</var> with the <em>exclude fragment flag</em> set.</li>
      <li>Run the following substeps in parallel:
        <ol>
          <li>If the <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a> of <var>scope</var> does not match <var>document</var>'s <a href="https://html.spec.whatwg.org/multipage/browsers.html#origin-2">origin</a>, then:
            <ol>
              <li>Reject <var>promise</var> with a "<code><a href="http://heycam.github.io/webidl/#securityerror">SecurityError</a></code>" exception.</li>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>Let <var>registration</var> be the result of running <a href="#get-registration-algorithm">Get Registration</a> algorithm passing <var>scope</var> as the argument.</li>
          <li>If <var>registration</var> is null, then:
            <ol>
              <li>Resolve <var>promise</var> with false.</li>
              <li>Abort these steps.</li>
            </ol>
          </li>
          <li>Set <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a>.</li>
          <li>Resolve <var>promise</var> with true.</li>
          <li>If no document is <a href="#dfn-use">using</a> <var>registration</var> as their <a href="#dfn-service-worker-registration">service worker registration</a>, then:
            <ol>
              <li>If <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a> is unset, then:
                <ol>
                  <li>Abort these steps.</li>
                </ol>
              </li>
              <li>Invoke <a href="#clear-registration-algorithm">Clear Registration</a> algorithm passing <var>registration</var> as its argument.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Return <var>promise</var>.</li>
    </ol>
    </div>
  </section>

  <section id="set-registration-algorithm"><header><span class="section-number">8.11</span> <h1 data-bookmark-label="8.11 Set Registration">Set Registration</h1><span class="anchor"><a style="text-decoration: none;" href="#set-registration-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>scope</var>, a <a href="#dfn-scope-url">scope url</a></dd>
      <dt>Output</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
    </dl>
    <ol>
      <li>Run the following steps atomically.</li>
      <li>Let <var>registration</var> be a new <a href="#dfn-service-worker-registration">service worker registration</a> whose <a href="#dfn-scope-url">scope url</a> is set to <var>scope</var>.</li>
      <li>Set a newly-created Record {[[key]]: <var>scope</var>, [[value]]: <var>registration</var>} to <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a>.</li>
      <li>Return <var>registration</var>.</li>
    </ol>
    </div>
  </section>

  <section id="clear-registration-algorithm"><header><span class="section-number">8.12</span> <h1 data-bookmark-label="8.12 Clear Registration">Clear Registration</h1><span class="anchor"><a style="text-decoration: none;" href="#clear-registration-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
      <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li>Run the following steps atomically.</li>
      <li>If <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> is not null, then:
        <ol>
          <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> and <em>redundant</em> as the arguments.</li>
          <li>Set <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> to null.</li>
          <li>The user agent may abort in-flight requests triggered by <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
        </ol>
      </li>
      <li>If <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> is not null, then:
        <ol>
          <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>.</li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> and <em>redundant</em> as the arguments.</li>
          <li>Set <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> to null.</li>
          <li>The user agent may abort in-flight requests triggered by <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>.</li>
        </ol>
      </li>
      <li>If <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> is not null, then:
        <ol>
          <li><a href="https://html.spec.whatwg.org/multipage/workers.html#terminate-a-worker">Terminate</a> <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
          <li>Run the <a href="#update-state-algorithm">Update State</a> algorithm passing <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> and <em>redundant</em> as the arguments.</li>
          <li>Set <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> to null.</li>
          <li>The user agent may abort in-flight requests triggered by <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
        </ol>
      </li>
      <li>Delete a Record {[[key]], [[value]]} <var>entry</var> of its <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a> where <var>registration</var>'s <a href="#dfn-scope-url">scope url</a> matches <var>entry</var>.[[key]].</li>
    </ol>
    </div>
  </section>

  <section id="update-state-algorithm"><header><span class="section-number">8.13</span> <h1 data-bookmark-label="8.13 Update State">Update State</h1><span class="anchor"><a style="text-decoration: none;" href="#update-state-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>worker</var>, a <a href="#dfn-service-worker">service worker</a></dd>
        <dd><var>state</var>, a <a href="#dfn-service-worker">service worker</a>'s <a href="#dfn-state">state</a></dd>
      <dt>Output</dt>
        <dd>None</dd>
    </dl>
    <ol>
      <li>Set <var>worker</var>'s <a href="#dfn-state">state</a> to <var>state</var>.</li>
      <li>Let <var>serviceWorkers</var> be an array containing all the <code><a href="#service-worker-interface">ServiceWorker</a></code> objects associated with <var>worker</var> for all the <a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context">browsing contexts</a>' <a href="https://dom.spec.whatwg.org/#document">Document</a> objects and the <code><a href="#service-worker-global-scope-interface">ServiceWorkerGlobalScope</a></code> object represented by <var>worker</var>.</li>
      <li>For each <var>serviceWorker</var> in <var>serviceWorkers</var>:
        <ol>
          <li><a href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task">Queue a task</a> to <a href="https://html.spec.whatwg.org/#fire-a-simple-event">fire a simple event named</a> <code>statechange</code> at <var>serviceWorker</var>.</li>
        </ol>
      </li>
    </ol>
    </div>
  </section>

  <section id="scope-match-algorithm"><header><span class="section-number">8.14</span> <h1 data-bookmark-label="8.14 Match Scope">Match Scope</h1><span class="anchor"><a style="text-decoration: none;" href="#scope-match-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>scope</var>, a <a href="#dfn-scope-url">scope url</a></dd>
      <dt>Output</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
    </dl>
    <ol>
      <li>Run the following steps atomically.</li>
      <li>Let <var>matchingScope</var> be the longest [[key]] in <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a> starting with the value of <var>scope</var>.</li>
      <li>Let <var>registration</var> be the result of running <a href="#get-registration-algorithm">Get Registration</a> algorithm passing <var>matchingScope</var> as the argument.</li>
      <li>If <var>registration</var> is not null and <var>registration</var>'s <a href="#dfn-uninstalling-flag">uninstalling flag</a> is set, then:
        <ol>
          <li>Return null.</li>
        </ol>
      </li>
      <li>Return <var>registration</var>.</li>
    </ol>
    </div>
  </section>

  <section id="get-registration-algorithm"><header><span class="section-number">8.15</span> <h1 data-bookmark-label="8.15 Get Registration">Get Registration</h1><span class="anchor"><a style="text-decoration: none;" href="#get-registration-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>scope</var>, a <a href="#dfn-scope-url">scope url</a></dd>
      <dt>Output</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
    </dl>
    <ol>
      <li>Run the following steps atomically.</li>
      <li>Let <var>registration</var> be null.</li>
      <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#scope-to-registration-map">[[ScopeToRegistrationMap]]</a>:
        <ol>
          <li>If <var>scope</var> matches <var>entry</var>.[[key]], then:
            <ol>
              <li>Set <var>registration</var> to <var>entry</var>.[[value]].</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Return <var>registration</var>.</li>
    </ol>
    </div>
  </section>

  <section id="get-newest-worker-algorithm"><header><span class="section-number">8.16</span> <h1 data-bookmark-label="8.16 Get Newest Worker">Get Newest Worker</h1><span class="anchor"><a style="text-decoration: none;" href="#get-newest-worker-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>registration</var>, a <a href="#dfn-service-worker-registration">service worker registration</a></dd>
      <dt>Output</dt>
        <dd><var>worker</var>, a <a href="#dfn-service-worker">service worker</a></dd>
    </dl>
    <ol>
      <li>Run the following steps atomically.</li>
      <li>Let <var>newestWorker</var> be null.</li>
      <li>If <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a> is not null, then:
        <ol>
          <li>Set <var>newestWorker</var> to <var>registration</var>'s <a href="#dfn-installing-worker">installing worker</a>.</li>
        </ol>
      </li>
      <li>Else if <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a> is not null, then:
        <ol>
          <li>Set <var>newestWorker</var> to <var>registration</var>'s <a href="#dfn-waiting-worker">waiting worker</a>.</li>
        </ol>
      </li>
      <li>Else if <var>registration</var>'s <a href="#dfn-active-worker">active worker</a> is not null, then:
        <ol>
          <li>Set <var>newestWorker</var> to <var>registration</var>'s <a href="#dfn-active-worker">active worker</a>.</li>
        </ol>
      </li>
      <li>Return <var>newestWorker</var>.</li>
    </ol>
    </div>
  </section>

  <section id="query-cache-algorithm"><header><span class="section-number">8.17</span> <h1 data-bookmark-label="8.17 Query Cache">Query Cache</h1><span class="anchor"><a style="text-decoration: none;" href="#query-cache-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>request</var>, a <code><a href="https://fetch.spec.whatwg.org/#request">Request</a></code> object</dd>
        <dd><var>options</var>, a <code><a href="#cache-query-options-dictionary">CacheQueryOptions</a></code> object, optional</dd>
        <dd><var>targetStorage</var>, an array that has [<code><a href="https://fetch.spec.whatwg.org/#request">Request</a></code>, <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>] pairs as its elements, optional</dd>
      <dt>Output</dt>
        <dd><var>resultArray</var>, an array that has [<code><a href="https://fetch.spec.whatwg.org/#request">Request</a></code>, <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code>] pairs as its elements</dd>
    </dl>
    <ol>
      <li>Let <var>requestArray</var> be an empty array.</li>
      <li>Let <var>responseArray</var> be an empty array.</li>
      <li>Let <var>resultArray</var> be an empty array.</li>
      <li>If <var>options</var>.<var>ignoreMethod</var> is false and <var>request</var>.<var>method</var> is neither "GET" nor "HEAD", then:
        <ol>
          <li>Return <var>resultArray</var>.</li>
        </ol>
      </li>
      <li>Let <var>cachedURL</var> and <var>requestURL</var> be null.</li>
      <li>Let <var>serializedCachedURL</var> and <var>serializedRequestURL</var> be null.</li>
      <li>If the optional argument <var>targetStorage</var> is omitted, then:
        <ol>
          <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#request-to-response-map">[[RequestToResponseMap]]</a>, in key insertion order:
            <ol>
              <li>Set <var>cachedURL</var> to <var>entry</var>.[[key]]'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>.</li>
              <li>Set <var>requestURL</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>.</li>
              <li>If <var>options</var>.<var>ignoreSearch</var> is true, then:
                <ol>
                  <li>Set <var>cachedURL</var>'s <a href="https://url.spec.whatwg.org/#concept-url-query">query</a> to the empty string.</li>
                  <li>Set <var>requestURL</var>'s <a href="https://url.spec.whatwg.org/#concept-url-query">query</a> to the empty string.</li>
                </ol>
              </li>
              <li>Set <var>serializedCachedURL</var> to <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <var>cachedURL</var>.</li>
              <li>Set <var>serializedRequestURL</var> to <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <var>requestURL</var>.</li>
              <li>If <var>options</var>.<var>prefixMatch</var> is true, then:
                <ol>
                  <li>Set <var>serializedCachedURL</var> to the substring of itself from the start, with the length of <var>serializedRequestURL</var>.</li>
                </ol>
              </li>
              <li>If <var>serializedCachedURL</var> matches <var>serializedRequestURL</var>, then:
                <ol>
                  <li>Add <var>entry</var>.[[key]] to <var>requestArray</var>.</li>
                  <li>Add <var>entry</var>.[[value]] to <var>responseArray</var>.</li>
                </ol>
              </li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Else:
        <ol>
          <li>For each <var>record</var> in <var>targetStorage</var>:
            <ol>
              <li>Set <var>cachedURL</var> to <var>record</var>[0]'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>.</li>
              <li>Set <var>requestURL</var> to <var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>.</li>
              <li>If <var>options</var>.<var>ignoreSearch</var> is true, then:
                <ol>
                  <li>Set <var>cachedURL</var>'s <a href="https://url.spec.whatwg.org/#concept-url-query">query</a> to the empty string.</li>
                  <li>Set <var>requestURL</var>'s <a href="https://url.spec.whatwg.org/#concept-url-query">query</a> to the empty string.</li>
                </ol>
              </li>
              <li>Set <var>serializedCachedURL</var> to <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <var>cachedURL</var>.</li>
              <li>Set <var>serializedRequestURL</var> to <a href="https://url.spec.whatwg.org/#concept-url-serializer">serialized</a> <var>requestURL</var>.</li>
              <li>If <var>options</var>.<var>prefixMatch</var> is true, then:
                <ol>
                  <li>Set <var>serializedCachedURL</var> to the substring of itself from the start, with the length of <var>serializedRequestURL</var>.</li>
                </ol>
              </li>
              <li>If <var>serializedCachedURL</var> matches <var>serializedRequestURL</var>, then:
                <ol>
                  <li>Add <var>record</var>[0] to <var>requestArray</var>.</li>
                  <li>Add <var>record</var>[1] to <var>responseArray</var>.</li>
                </ol>
              </li>
            </ol>
          </li>
        </ol>
      </li>
      <li>For each <var>cachedResponse</var> in <var>responseArray</var> with the index <var>index</var>:
        <ol>
          <li>Let <var>cachedRequest</var> be the <var>index</var>th element in <var>requestArray</var>.</li>
          <li>If the result of running <var>cachedResponse</var>.<a href="https://fetch.spec.whatwg.org/#dom-response-headers">headers</a> object's <code><a href="https://fetch.spec.whatwg.org/#dom-headers-has">has(<var>name</var>)</a></code> method with "Vary" as the argument is false, or <var>options</var>.<var>ignoreVary</var> is true, then:
            <ol>
              <li>Add an array [<var>cachedRequest</var>, <var>cachedResponse</var>] to <var>resultArray</var>.</li>
              <li>Continue to the next iteration of the loop.</li>
            </ol>
          </li>
          <li>Let <var>varyHeaders</var> be the array containing the elements corresponding to the <a href="http://tools.ietf.org/html/rfc2616#section-4.2">field-values</a> of the <a href="http://tools.ietf.org/html/rfc2616#section-14.44">Vary</a> header.</li>
          <li>Let <var>matchFailed</var> be false.</li>
          <li>For each <var>f</var> in <var>varyHeaders</var>:
            <ol>
              <li>If <var>f</var> matches "*", then:
                <ol>
                  <li>Continue to the next iteration of the loop.</li>
                </ol>
              </li>
              <li>If the result of running <var>cachedRequest</var>.<a href="https://fetch.spec.whatwg.org/#dom-request-headers">headers</a> object's <code><a href="https://fetch.spec.whatwg.org/#dom-headers-get">get(<var>name</var>)</a></code> method with <var>f</var> as the argument does not match the result of running <var>request</var>.<a href="https://fetch.spec.whatwg.org/#dom-request-headers">headers</a> object's <code><a href="https://fetch.spec.whatwg.org/#dom-headers-get">get(<var>name</var>)</a></code> method with <var>f</var> as the argument, then:
                <ol>
                  <li>Set <var>matchFailed</var> to true.</li>
                  <li>Break the loop.</li>
                </ol>
              </li>
            </ol>
          </li>
          <li>If <var>matchFailed</var> is false, then:
            <ol>
              <li>Add an array [<var>cachedRequest</var>, <var>cachedResponse</var>] to <var>resultArray</var>.</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Return <var>resultArray</var>.</li>
    </ol>
    </div>
  </section>

  <section id="batch-cache-operations-algorithm"><header><span class="section-number">8.18</span> <h1 data-bookmark-label="8.18 Batch Cache Operations">Batch Cache Operations</h1><span class="anchor"><a style="text-decoration: none;" href="#batch-cache-operations-algorithm">¶</a></span></header>


    <div class="algorithm">
    <dl>
      <dt>Input</dt>
        <dd><var>operations</var>, an array of  <code><a href="#cache-batch-operation-dictionary">CacheBatchOperation</a></code> dictionary objects</dd>
      <dt>Output</dt>
        <dd><var>q</var>, a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolves with an array of <code><a href="https://fetch.spec.whatwg.org/#response">Response</a></code> objects.</dd>
    </dl>
    <ol>
      <li>Let <var>p</var> be a <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects">promise</a> resolved with no value.</li>
      <li>Let <var>q</var> be <a href="http://www.w3.org/2001/tag/doc/promises-guide#transforming-by">transforming <var>p</var> with <var>onFulfilled</var></a>.</li>
      <li><a href="http://www.w3.org/2001/tag/doc/promises-guide#upon-fulfillment">Upon fulfillment of <var>p</var> with value <var>v</var></a>, perform the following substeps, <var>onFulfilled</var>, in parallel:
        <ol>
          <li>Let <var>itemsCopy</var> be a new <a href="#request-to-response-map">[[RequestToResponseMap]]</a> object that is a copy of its <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#request-to-response-map">[[RequestToResponseMap]]</a> object.</li>
          <li>Let <var>addedRecords</var> be an empty array.</li>
          <li>Try running the following substeps atomically:
            <ol>
              <li>Let <var>resultArray</var> be an empty array.</li>
              <li>For each <var>operation</var> in <var>operations</var> with the index <var>index</var>:
                <ol>
                  <li>If <var>operation</var>.<var>type</var> matches neither "delete" nor "put", then:
                    <ol>
                      <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> a TypeError.</li>
                    </ol>
                  </li>
                  <li>If <var>operation</var>.<var>type</var> matches "delete" and <var>operation</var>.<var>response</var> is not null, then:
                    <ol>
                      <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> a TypeError.</li>
                    </ol>
                  </li>
                  <li>Let <var>requestResponseArray</var> be the result of running <a href="#query-cache-algorithm">Query Cache</a> algorithm passing <var>operation</var>.<var>request</var> and <var>operation</var>.<var>options</var> as the arguments.</li>
                  <li>For each <var>requestResponse</var> in <var>requestResponseArray</var>:
                    <ol>
                      <li>If the result of running <a href="#query-cache-algorithm">Query Cache</a> algorithm passing <var>requestResponse</var>[0], <var>operation</var>.<var>options</var>, and <var>addedRecords</var> as the arguments is not an empty array, then:
                        <ol>
                          <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> an "<code><a href="http://heycam.github.io/webidl/#invalidstateerror">InvalidStateError</a></code>" exception.</li>
                        </ol>
                      </li>
                      <li>For each Record {[[key]], [[value]]} <var>entry</var> of its <a href="#request-to-response-map">[[RequestToResponseMap]]</a>, in key insertion order:
                        <ol>
                          <li>If the result of running <a href="#query-cache-algorithm">Query Cache</a> algorithm passing <var>requestResponse</var>[0] and <var>operation</var>.<var>options</var> is equal to the result of running <a href="#query-cache-algorithm">Query Cache</a> algorithm passing <var>entry</var>.[[key]] and <var>operation</var>.<var>options</var>, then:
                          <ol>
                            <li>Delete <var>entry</var>.</li>
                          </ol>
                        </li>
                        </ol>
                      </li>
                    </ol>
                  </li>
                  <li>If <var>operation</var>.<var>type</var> matches "put", then:
                    <ol>
                      <li>If <var>operation</var>.<var>response</var> is null, then:
                        <ol>
                          <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> a TypeError.</li>
                        </ol>
                      </li>
                      <li>Let <var>r</var> be <var>operation</var>.<var>request</var>'s associated <a href="https://fetch.spec.whatwg.org/#concept-request-request">request</a>.</li>
                      <li>If <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-url">url</a>'s <a href="https://url.spec.whatwg.org/#concept-url-scheme">scheme</a> is not one of "<code>http</code>" and "<code>https</code>", then:
                        <ol>
                          <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> a TypeError.</li>
                        </ol>
                      </li>
                      <li>If <var>r</var>'s <a href="https://fetch.spec.whatwg.org/#concept-request-method">method</a> is not `<code>GET</code>`, then:
                        <ol>
                          <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> a TypeError.</li>
                        </ol>
                      </li>
                      <li>If <var>operation</var>.<var>options</var> is not null, then:
                        <ol>
                          <li><a href="http://heycam.github.io/webidl/#dfn-throw">Throw</a> a TypeError.</li>
                        </ol>
                      </li>
                      <li>Set a newly-created Record {[[key]]: <var>operation</var>.<var>request</var>, [[value]]: <var>operation</var>.<var>response</var>} to <a href="#request-to-response-map">[[RequestToResponseMap]]</a>.</li>
                      <li>Add an array [<var>operation</var>.<var>request</var>, <var>operation</var>.<var>response</var>] to <var>addedRecords</var>.</li>
                    </ol>
                  </li>
                  <li>Add <var>operation</var>.<var>response</var> to <var>resultArray</var>.</li>
                </ol>
              </li>
              <li>Resolve <var>q</var> with <var>resultArray</var>.</li>
            </ol>
          </li>
          <li>And then, if an exception was <a href="http://heycam.github.io/webidl/#dfn-throw">thrown</a>, then:
            <ol>
              <li>Set the <a href="https://dom.spec.whatwg.org/#context-object">context object</a>'s <a href="#request-to-response-map">[[RequestToResponseMap]]</a> to <var>itemsCopy</var>.</li>
              <li>Reject <var>q</var> with the exception</li>
            </ol>
          </li>
        </ol>
      </li>
      <li>Return <var>q</var>.</li>
    </ol>
    </div>
  </section>

</section>

<section id="acknowledgements"><header><span class="section-number">9</span> <h1 data-bookmark-label="9 Acknowledgements">Acknowledgements</h1><span class="anchor"><a style="text-decoration: none;" href="#acknowledgements">¶</a></span></header>

  <!-- FIXME: INCOMPLETE!! Please add collaborators below. -->

  <p id="acknowledgements.1">Jake Archibald is a ghost-author of this document. The best instincts in the design are his. He similarly shaped many of the details through discussion and experimentation. The bits which are not his (but which are good) owe everything to his experience, persistence, and focus on enabling web developers. He embodies a hopeful example for developers in shaping browser efforts to more directly address real-world pain points. If service workers solve "offline for the web", the credit is due him.</p>

  <p id="acknowledgements.2">Deep thanks go to Andrew Betts for organizing and hosting a small workshop of like-minded individuals including: Jake Archibald, Jackson Gabbard, Tobie Langel, Robin Berjon, Patrick Lauke, Christian Heilmann. From the clarity of the day's discussions and the use-cases outlined there, much has become possible. Further thanks to Andrew for raising consciousness about the offline problem. His organization of EdgeConf and inclusion of Offline as a persistent topic there has created many opportunities and connections that have enabled this work to progress.</p>

  <p id="acknowledgements.3">Anne van Kesteren has generously lent his encyclopedic knowledge of Web Platform arcana and standards development experience throughout the development of the service worker. This specification would be incomplete without his previous work in describing the real-world behavior of URLs, HTTP Fetch, Promises, and DOM. Similarly, this specification would not be possible without Ian Hickson's rigorous Web Worker spec. Much thanks to him.</p>

  <p id="acknowledgements.4">In no particular order, deep gratitude for design guidance and discussion goes to: Jungkee Song, Alec Flett, David Barrett-Kahn, Aaron Boodman, Michael Nordman, Tom Ashworth, Kinuko Yasuda, Darin Fisher, Jonas Sicking, Jesús Leganés Combarro, Mark Christian, Dave Hermann, Yehuda Katz, François Remy, Ilya Grigorik, Will Chan, Domenic Denicola, Nikhil Marathe, Yves Lafon, Adam Barth, Greg Simon, Devdatta Akhawe, Dominic Cooney, Jeffrey Yasskin, Joshua Bell, Boris Zbarsky, Matt Falkenhagen, Tobie Langel, Gavin Peters, and Ben Kelly.</p>

  <p id="acknowledgements.5">Jason Weber, Chris Wilson, Paul Kinlan, Ehsan Akhgari, and Daniel Austin have provided valuable, well-timed feedback on requirements and the standardization process.</p>

  <p id="acknowledgements.6">The authors would also like to thank Dimitri Glazkov for his scripts and formatting tools which have been essential in the production of this specification. The authors are also grateful for his considerable guidance.</p>

  <p id="acknowledgements.7">Thanks also to Vivian Cromwell, Greg Simon, Alex Komoroske, and Wonsuk Lee for their considerable professional support.</p>
</section>



</body></html>
